In this section we will see how to write tests with the framework mocked environment.
AgileSites provides a mocking enviroment to easily write unit tests.
Tests actually check the integrity of the java controller logic, content model and html view and they must be run from the integrated test runner that is generated by the site generator.
The test runner is accessible with http://localhost:8080/cs/ContentServer?pagename=mysite-tester
Change the mysite
to the lowercase version of your site name.
All the tests run by the tester are listed in app/src/resources/tests.txt
A test class is automatically created when you use the wcs-generate
and the class name is added to the list. Then you complete the test adding assertions that are based . Here is a typical test, whose meaning is explained in the following:
public class SummaryTest extends TestElement {
final static Log log = Log.getLog(SummaryTest.class);
Summary it;
@Before
public void setUp() {
it = new Summary();
}
@Test
public void testHome() {
parse(it.apply(env("")));
//dump(log);
assertText("h4", "Home");
assertTextContains("div div", "Welcome!");
}
@Test
public void testAbout() {
parse(it.apply(env("")));
//dump(log);
assertText("h4", "About");
assertTextContains("div div", "About us...");
}
}
Each test will exercise the java code of a template or cselement, implemented mostly as classes derived by theElement
base class. The main logic is in the apply
method that takes an Env
as argument.
Because tests exercise also the business logic applied to the cms, you need to run the tests with the Tester of your web site. Each test should extend the TestElement
base class, that is a jUnit4 test case.
Following the standard jUnit4 practices, you have to mark each test method with the @Test
annotation, initializations with @Before
and cleanup with @After
.
In the sample you see that the setUp
method will create an instance of the Element
class and then execute the tests.
Since the Env
is the facade used to access to all the other resources, a test must be run passing an Env
to the apply
method.
The test element provides an env(String)
method to generate a mocked TestEnv
. Thre result of the apply
methods is special String that is normally rendered by the CMS but the TestElement
provides also the the method parse
to parse the result in a way that is easy to analyze.
For this reason each test starts with:
parse(it.apply(env("")));
where env("")
will generate an enviroment, then it.apply
will run the code to be tested and finally parse
will prepare the result for analysis.
An important parameter of the env
method is the String parameter, that is passed to the router for initializing the enviroment. Check the routing documentation for details.
If you write env("")
then the mocked env will be the same as the enviroment generated by the url http://localhost:8080/cs/Satellite/mysite
, while the env("/Home")
will be the same as if you use the http://localhost:8080/cs/Satellite/mysite/About
. Indeed the Router receive always the part of the url that after the prefix /cs/Satellite/mysite
.
Because the router usually maps names in url, using ""
will initilize c/cid to c=Page
and the cid
of the Page Home, while the second will initialize the c/cid
to the ones of the page About
. Default router allows also to specificy /News/Today
to set c/cid to the asset of type
Demo_News
named Today
`.
Of course since the router is extensible, this behaviour can be changed. It really depends on the router implementation.
Once you have initialized the enviroment, you can finally run some assertions on it. Assertions are based on the same selectors used in the Picker
Available methods are:
assertText(selector, text)
will test that the text of the html selected by the selector is the same as the text.assertTextContains(selector, text)
will test that the text of the html selected by the selector contains the text.assertHtml(selector, htmltext)
will test that the inner html (tag included) selected by the selector is the same as the htmltext.assertOuterHtml(selector, htmltext)
will test that the outer html (tag included) selected by the selector is the same as the htmltext.assertAttr(selector, attribute, text)
will test that the attribute of the tag selected by the selector is the same as the text.assertAttrContains(selector, attribute, text)
will test that the attribute of the tag selected by the selector contains the text.You can use also generic assertions extracting a piece of text with text(selector)
, an attribute with attr(selector, attribute)
, selecting a subtree with select(selector)
and finally generally apply any JUnit assertions on nodes extracted by the current document, accessible with the doc
variable using JSoup methods.
When you debug a test, it is very helpful to use the logging support. From the shello, the command wcs-log view
will show a gui log viewer. This log viewer is socket based. You can start a server from the menu , that will propose by default a socket listening in port 4445. You can actually create multiple log windows listening in different ports. This way you may listen for example the log for the api in a windows and the log for your application in another windows.
You can then enable log at a given level for the package or class you want. For example wcs-log trace mysite
will start logging at the trace level all the classes in the package and in subpackage of the package mysite
(where usually is your site code).
You can also set anoter port in the log: wcs-log debug wcs 4444
will log at debug level everything in the package and subpackages wcs
(that is the package of the AgileSites API - remember to create a window in the log viewer to see the logs).
Last but not least: you can see which logs are enabled with wcs-log list
and you can stop a log stream, for example of the package mysite
with wcs-log stop mysite
.