In this section we will see how to write tests with the framework mocked environment.

## Test 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:

```java
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...");
	}
}
```

###  TestElement 

Each test will exercise the java code of a template or cselement, implemented mostly as classes derived by the`Element` 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.


### env()

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:

```java
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.


## initialize the mocked env

An important parameter of the `env` method is the String parameter, that is passed to the router for initializing the enviroment. Check the [routing](../reference/Routing.md) 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.


## Assertions

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](../reference/Picker.md)

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.

## Logger

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`.

