When writing the unitTests.qunit.html it is unclear to me how to do the QUnit includes and how to write the html structure.
When looking at the guides and sources, I see many different setups:
require and extended html structurerequire and not as extended htmlrequire and simple htmlIs there a best practice setup for QUnit test pages?
Is there an explanation, what the includes files do?
sap.ui.thirdparty.qunit: Actual QUnitsap.ui.qunit.qunit-css: QUnit stylingsap.ui.qunit.qunit-junit: ???sap.ui.qunit.qunit-coverage: Blanket code coveragesap.ui.qunit.QUnitUtils: ???sap.ui.thirdparty.require: ??? (Found in OpenUI5 code)Hello!
W/o looking at all the other examples, here's one more way to do it: my team has been separating the actual QUnit JavaScript code into a separate *.qunit.js file for years, with very good results. The *.qunit.html file is basically the same every time (just a different title and one different file to include). You can find one example here: ODataMetaModel.qunit.html
What is the advantage of this? Well, you can aggregate tests into s.th. larger, have overall code coverage measured, still select single modules, all w/o the overhead of loading multiple HTML files during a test suite run. You can find one example here: 1Ring.qunit.html
Hope it helps.
Best regards,
Thomas
P.S.: I guess some files are mainly needed for automatic execution and reporting of results.
@ThomasChadzelek Thanks for the reply.
My question is not about writing the actual tests, but about how the html should look like. Specifically the way to include QUnit (<script> vs. require) and the content of the body.
Hi Hirse,
in the docs of QUnit they consistently use the simpliefied html.
So all of our samples should probably use it too.
I actually would recommend the Explored sample if you want to have a good test isolation (all tests will run in the same HTML).
Why require > Script tags - I sometimes changed the nesting of an test.qunit.html site then you need to adjust all script tags. When using require you only need to touch the core stript tag.
Why are the QUnit includes itself done withjQuery.sap.require?
QUnit itself needs to be loaded before dom is ready to be able to set the setting QUnit.config.autostart = false
If you do not set this setting and you did not load all your tests yet QUnit will start and only execute the tests that were loaded before the dom is ready see the QUnit docs of autostart.
sap.ui.require Is not async yet but when it becomes async the tests would be loaded potentially afterDomReady so we wanted our new samples to be written in this way. But acutally we did not go over all the places in the docs and changed this consistently. Therefore i will open an internal issue to cleanup all this and bring more consistency.
tracked internally 1680227206.
For the test requires
sap.ui.qunit.qunit-junit: To have a junit report used for CI environments like Jenkinssap.ui.qunit.QUnitUtils: To trigger events on Controls in Javascript (clicking or key events)The missing requires i tend to use a lot:
jQuery.sap.require("sap.ui.thirdparty.sinon"); : Our main library for spying/stubbing and mocking dependenciesjQuery.sap.require("sap.ui.thirdparty.sinon-qunit"); Creates sinon sandboxes around unit tests (use with care does not work for async tests)jQuery.sap.require("sap.ui.thirdparty.sinon-ie"); Probably obsolete since we dropped IE9 had to do with fake time problems of sinon i thinkBest regards,
Tobias
Thanks for the detailed information, @TobiasOetzel.
I still have questions about the qunit-junit and QUnitUtils files:
sap.ui.test.actions?My QUnit.html files currently look like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Unit Tests for my.lib</title>
<script id="sap-ui-bootstrap"
src="/sap/ui5/1/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core, sap.m, my.lib"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-compatVersion="edge"
data-sap-ui-preload="async"
data-sap-ui-resourceroots='{"my.lib": "/my/lib"}'>
</script>
<script>
jQuery.sap.require("sap.ui.thirdparty.qunit");
jQuery.sap.require("sap.ui.qunit.qunit-css");
// Filter the code coverage by the tested library
jQuery.sap.require("sap.ui.qunit.qunit-coverage");
if (window.blanket) {
window.blanket.options("sap-ui-cover-only", "my/lib");
}
QUnit.config.autostart = false;
sap.ui.require([
"my/lib/Control1",
"my/lib/Control2"
], function () {
QUnit.start();
});
</script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
Do you see anything I could improve?
Is there a way to load all resources with sap.ui.require?
@TobiasOetzel : due to the deprecation of the sync XHR, I would NOT use jQuery.sap.require in a "best practice" template, but use a script tag for QUnit and a link for its CSS.
I understand the drawback of relative URLs, but either you might use
@Hirse: all files but the qunit.js itself should be loadable via sap.ui.require. But when you load qunit-coverage with sap.ui.require, you won't find the right point in time to configure the includes/excludes. So IMHO it makes sense to load qunit-coverage also via script tag (you then can add the configuration in the script tag, thank's to your pull request :-) ).
There is a test case that was intended as a kind of "Best practice" template for QUnit tests, but it still doesn't reflect all the points from this thread here. I guess we should update it when working on the internal ticket 1680227206.
Hi again,
@codeworrior raised a good point. So probably we should use a script tag for QUnit.
Internally in OpenUI5 and in most of the apps that get developed the URLs are really relative to the html site not to the server.
As pointed out has to be solved in the ticket.
So first your QUnit.html file looks very good to me.
I would probably also require sinon.js because it is so useful for almost every QUnit i write. Sinin can be safely required with sap.ui.require.
So quite some work for the ticket piled up
Hi,
after a bit of silence i put up a pull request to QUnit.
So we will be able to set autostart: false before loading QUnit. Then we may load it with a regular require statement.
@TobiasOetzel I highly appreciate your contribution to QUnit, but I guess it will go to jQuery 2.0.x, or? Migrating to 2.0.x will cause a significant effort on our side. I'm not at all against such a migration, it is indeed overdue. I just wanted to raise that point as it might require some joined effort...
Or we have to deviate again from the self-imposed rule that only one version of an OSS should be embedded in sap/ui/thirdparty/.
I wanted to fork our thirdpary folder until we update with the exact same behaviour. If we really want to migrate later on, or use QUnit 2 by altering the require we have the same code running.
I don't know if we will update QUnit 1.x too often. I can also checkout if it can be downported to QUnit 1.x maintanence line.
I just wanted to wait for the forkin if the API I had in mind is ok for the QUnit team.
Update: openui5 code base (all unit tests) have been lifted to QUnit 2.0 syntax now (phew that was some work). Real Migration to QUnit 2.0 is still pending though as we have some hard dependencies to dissolve first
I also created a convenience API "QUnitLoader" based on Tobias change referenced above. When it is merged, we will update our best practices for writing test pages. Until then, our best practices are documented in the "Testing Tutorial" and in the Testing documentation in the developer guide.
in the meanwhile, we found this pattern useful for us:
https://github.com/SAP/openui5/blob/master/src/sap.ui.rta/test/sap/ui/rta/qunit/Utils.qunit.html
https://github.com/SAP/openui5/blob/master/src/sap.ui.rta/test/sap/ui/rta/qunit/Utils.qunit.js
Hello @Hirse,
as you saw we meanwhile updated our recommendations for testing several times. With the 1.58 release we have rebuilt the walkthrough step 28+29 and the testing tutorial to show the latest recommendations. Also, the OPA samples and the documentation got renewed, the only source from above that was not updated yet is the internal QUnit unit test, but that should not be of any further relevance.
QUnit: https://openui5nightly.hana.ondemand.com/#/topic/e1ce1de315994a02bf162f4b3b5a9f09
OPA: https://openui5nightly.hana.ondemand.com/#/topic/9bf4dce43b7943d0909cd6c58a933589
In a nutshell these are:
In 1.60 which is the next relesse, we will again update our recommendations to new APIs from the UI5 development teams and explain them in our tutorials.
I hope that answered all questions that were left open long time ago.
Let us know if there is anything in addition to clarify
Michael
UI5 Develpment
PS: The QUnitUtils class contains helper functions for working with UI5 and qunit - such as event simulations on controls
Thanks for coming back on this, @Michadelic.
@Michadelic I think we need to update our docs to sinon-4 since it's available under sap/ui/thirdparty/sinon-4 for a while already ;-)
Most helpful comment
Hi,
after a bit of silence i put up a pull request to QUnit.
So we will be able to set autostart: false before loading QUnit. Then we may load it with a regular require statement.