GUI Testing without Service Implementations
This project illustrates a way to perform integration testing on GUI applications. The service layer is mocked using Easymock. Thus, we define use-cases in TestFx by mocking the service layer. Our test suite is organized in such a way that our future service implementation will inherit of the planned test defined initially with mocks. The whole source code can be found in Github.
The Service layer (model package)
Our service is a very simple service whose goal is to handle a set of users (add a user, delete a user and get all users). It is composed of the main interface UserService and an abstract class User. We add also a factory ServiceFactory. A user has a last name and a first name.
The JFx views (views package)
This application is really minimalist. The menu is composed of two buttons (views.Menu): Delete a user and quit. Clicking on Delete a user leads you toward a lovely pane (views.UserList) composed of a listview (ListView) and two buttons (delete a user and menu).
The Controller (controller package)
Basically, like in any MVC application, the controller has its orchestral role.
What are these Story-lines?
In the class MainTest, one can denote two basic story-lines in two @Test functions:
A user runs the application, click on delete a user, select a user in the listview, click on the delete button and finally cancel his action. The class StoryLineSelectAUserAndCancel explicitly defines what we expect about an instance of the class UserService in this story-line.
A user runs the application, click on delete a user, select a user in the listview, click on the delete button and finally confirm his action. The class StoryLineSelectAUserAndConfirmMock explicitly defines what we expect about an instance of the class UserService in this story-line.
In the package storylines.mocks, both story-line classes express in their method execute() what we expect about a mock of the class UserService in this story-line. For instance, it corresponds to an initialization of the used mock (see right below, the class StoryLineSelectAUserAndConfirmMock).
Each story-line is associated to a @Test method by a factory (see in the test environment: storylines.mocks.StorylineFactoryMocks). The String constants are defined in the abstract class: MainTest.
Discussion about the abstract class MainTest
Let us focus on the class MainTest. The whole test suite is defined under the hypothesis that a story-line factory and a user service factory are sufficient. And that is the case.
The test case click and cancel is defined using the TestFx library in order to simulate a human interaction.
The test case click and confirm is defined as well.
Finally, you can find some extra functions in particular for timing the animation.
The interesting point is that one can define the functional tests without any implementation of the service layer. And thus, those functional tests can be considered as integration tests for the next implementations of the services. This exercise is in the scope of decoupling the functional tests of their implementations when they are encoded as unit tests.