Should I include system tests in a Spring project? - spring

My Spring web project consists of:
util classes;
repositories;
services;
controllers.
The tests are as follows:
unit tests for util classes;
spring integration tests for repositories with HSQLDB;
unit tests for services with mock repositories;
unit tests for controllers with mock services.
There also may be system tests which test the overall project functionality. It can be performed with an external tool like Selenium or it can be performed using Spring integration testing.
The question is, should I include such spring integration system tests in a project or should they be separated somehow?
I see two problems about including system tests in a project:
1. they need configuration tuning because such tests will not run with production config (e.g. tests need a local datasource, not the one from JNDI);
2. they aren't autonomous, they need some external resources and so on. I cannot just run them as usual unit tests.
How do you organize your system testing?

On small projects I've kept them in the same place. On large enterprise projects (the kind for which you might usefully leverage Spring, for instance) we've usually organised system tests in a separate package / project. This helps keep them separate from the main codebase.
If you don't do this, there's all kinds of temptation to reuse classes from the code to "help out" in something which should be more strongly focused on the experience of users of the system (a user may be another system). If this happens, you end up with coupling between the project domain classes and the UI, which will have the inevitable effect of needing to duplicate much of the logic which helps keep them decoupled in the real codebase.
Most of the time the logic in system scenarios will actually be focused on pages, screens, web-calls, etc. so reusing code from the main project is a red herring. Keep the packages separate to avoid this happening, and because once you avoid it happening there's no need to have them in the same place.
Do, however, make sure that the system tests are checked in to the same version control as the code.
If you're not doing continuous integration and testing / deployment yet, that might be another area for which some learning will help you with the config files. That problem doesn't go away just because you have tests in a separate project, unfortunately.

Related

Is it worth implementing service integration tests in Spring Boot application?

I have come accross multiple articles on integration testing on Spring Boot applications. Given that the application follows three layer pattern (Web Layer - Service Layer - Repository Layer) I have not seen a single article with integration testing the application up to just the service layer (ommiting the web layer) where all the business logic is contained. All of the integration tests seem like controller unit tests - mostly veryfing only request and response payloads, parameters etc.
What I would like however is to verify the business logic using service integration tests. Since the web layer is responsible only for taking the results from services and exchanging them with the client I think this makes much more sense. Such tests could also contain some database state verifications after running services to e.g. ensure that there are no detached leftovers.
Since I have never seen such a test, is it a good practice to implement one? If no, then why?
There is no one true proper way to test Spring applications. A general approach is as you described:
slices tests (#DataJpaTest, #WebMvcTest) etc for components that heavily rely on Spring
unit tests for domain classes and service layer
small amount of e2e tests (#SpringBootTest) to see if everything is working together properly
Spotify engineers on the other hand wrote how they don't do almost any unit testing and everything is covered with integration tests that covered with integration tests.
There is nothing stopping you from using #SpringBootTest and test your service layer with all underlying components. There are things you need to consider:
it is harder to prepare test data (or put system under certain state), as you need to put them into the database
you need to clean the database by yourself, as (#SpringBootTest) does not rollback transactions
it is harder to test edge cases
you need to mock external HTTP services with things like Wiremock - which is also harder than using regular Mockito
you need to take care of how many application contexts you create during tests - first that it's slow, second each application context will connect to the database, so you will create X connections per context and eventually you can reach limits of your database server.
This is borderline opinion-based, but still, I will share my take on this.
I usually follow Mike Cohn's original test pyramid such as depicted below.
The reason is that unit tests are not only easier to write but also faster and most likely cover much more than other more granular tests.
Then we come across the service or integration tests, the ones you mention in your question. They are usually harder to write simply because you are now testing the whole application and not only a single class and take longer to run. The benefit is that you are able to test a given scenario and most probably they do not require as much maintenance as the unit tests when you need to change something in your code.
However, and here comes the opinion part, I usually prefer to focus much more on writing good and extensive unit tests (but not too much on test coverage and more on what I expect from that class) than on fully-fledged integration tests. What I do like to do is take advantage of Spring Slice Tests which in the pyramid would be placed between the Unit Tests and the Service Tests. They allow you to focus on a specific class (a Controller for example) but they also allow you to test some integration with the underlying Spring Framework or infrastructure. This is for me the best of both worlds. You can still focus on a single class but also test some relevant components of your application. You can test your web layer with #WebMvcTest or #WebFluxTest (so that you can test JSON deserialization and serialization, bean validation, etc...), or you can focus on your persistence layer with #DataJpaTest, #JdbcTest or #DataMongoTest (so that you can test the actual persistence and retrieval of data).
Wrapping up, I usually write a bunch of Unit Tests and then web layer tests to check my Controllers and also some persistence layer tests against a real database.
You can read more in the following interesting online resources:
https://martinfowler.com/articles/practical-test-pyramid.html
https://www.baeldung.com/spring-tests

Other ways of MVC 3 Asp.net testing

I am currently testing MVC 3 Controller and views using HTML and notepad. Is there other ways to do testing if you cannot modify the code? Like for example creating a seperate project to do testing?
Assuming that you have the capacity to create a test project or two which can tap into the web application, you essentially have to basic tools at your disposal:
Unit tests
Coded UI tests
Unit tests are used to test specific components of your application. If your application has a nice architecture which takes dependency injection into account, there is very little in MVC that you cannot unit test to some extent. The advantage of unit tests is that they help find the source of bugs in your code (as they are small, targeted tests) and that they help prevent regressions when refactoring or adding new functionality.
Coded UI tests are used to test user-facing features in your application and serve as integration tests which allow you to test the entire application stack, including the user interface. They are recorded just like you would record a macro in MS Office.
Both of these can be done nonintrusively. You'll need access to the original solution (or at least the DLLs and a hosted version of the website at the very least.
For more information on unit tests: http://msdn.microsoft.com/en-us/library/dd264975.aspx
For more information on Coded UI tests: http://msdn.microsoft.com/en-us/library/dd286726.aspx

Maven Multi Module benefits over simple dependency

I have some years of experience with maven projects, even with multi modules ones (which has made me hate the multi modules feature of maven (so the disclaimer is now done)) and even if I really like maven there is something I cannot get a clear answer about :
What is a typical usecase of a multi module maven project ? What is the added value of such a structure compared to simple dependencies and parent pom ?
I have seen a lot of configuration of multi module projects but all of them could have clearly been addressed by creating a simple structure of dependency library living their own life as deliverables (even with a parent pom, as a separate deliverable : factorising depedencies and configuration) and I haven't found any usecase where I can clearly see an added value of the multi module structure.
I have always found that this kind of structure brings an overkilling complexity with no real benefit : where am I missing something ? (to be truly honest, I can get that some ear can benefit from this kind of structure but except from that particular usecase, any other real use and benefit ?)
Here's a real life case.
I have a multi-module project (and to your rant... I haven't seen any complications with it.) The end result is a webapp but I have different modules for api, impl, and webapp.
12 months after creating the project I find that I have to integrate with Amazon S3 using a stand-alone process run from a jar. I add a new module which depends on api/impl and write my code for the integration in the new module. I use the assembly plugin (or something like it) to create a runnable jar and now I have a war I can deploy in tomcat and a process I can deploy on another server. I have no web classes in my S3 integration process and I have no Amazon dependencies in my webapp but I can share all the stuff in api and impl.
3 months after that we decide to create a REST webapp. We want to do it as a separate app instead of just new URL mappings in the existing webapp. Simple. One more module, another webapp created as the result of the maven build with no special tinkering. Business logic is shared easily between webapp and rest-webapp and I can deploy them as needed.
The major benefit of multi modules are
one single maven command to build all your modules at once.
and the most important : maven take care of the build order for you.
configuring your CI-server is also very easy: one single jenkins job to build everything.
I already worked in a project with about 30 submodules. Sometimes, you need to change something in more than module, and running one single command and being sure that everything that need to be compiled is compiled in the correct order is a must.
EDIT
Why 30 submodules ?
Huge framework with lot's a features, lot's of developers, separation of features on a module base. It's a real life use case and the separation of the code into module was really meaningful.
I think you are correct in that most project that use multi modules, actually don't need them.
At where I work we use multimodule projects (and I think that for a good reason). We have something similar to a service oriented architecture, so each application
A client module
An interface module (which has shared objects between the client and implementation)
an implementation module
a war module
I agree that putting that implementation and war module in the same actual module would be ok, but the (arguably) benefit of this is that is very clear division between the classes that solve the problem and how the application communicates with the external world.
In previous projects that involved just a web application, I've tried to put everything in the same module, as it made testing easier, given the modules I was using.
Multi modules can help you with re-use your code.
It's one of the best benefits you'll feel in work.
Imagine if you have 3 web projects with a security layer, You'll have to copy paste your code 3 times and trying connect it with each project.
But what if you create a security module a project with a specific job.
It'll be easy to use it by injecting it to your app and then boom it works.
Also as mentioned in #ben75's answer the one maven build command and the correct order of building all your used jars. You'll think no more about which depends on another.
I find maven modules extremely useful for the following reasons:
Architecture layering and boundaries
For example, I make a maven module application-contract which contains the interfaces my presentation layer sees. So I have UI->Presenter-> application-contract <-application-impl <- infrastructure -> domain. This way, I know that my presentation/UI layer will not have access to classes from my Domain/application layers. If domain classes are not in classpath when I code in UI, I cant use them. And I like it this way (utilizing the class path restrictions). Perhaps Java 9 modules can solve this problem too, but (unfortunately) I have work with Java 8.
Running tests in one module each time
When I change code to a layer which is a module (as mentioned previously) I can run its tests only, without re-runing tests from code I did not change. This gives me speed. My presentation layer tests need ~3 seconds (for 300 tests). Every time I change code to a Presenter or whatever below application layer, I don't want my database H2 integration tests to run. Or My Image processing tests to run. Because these do IO and they are slow.
Building
Pretty much the same thing. When I change code to UI, i have only to build and deploy UI stuff (my UI is in Java).

TeamCity - Reporting on success of multiple projects configurations in one place

We currently have TeamCity setup so we have a project per component (Website, APIs, Mobile App, etc). Each project contains a Functional Tests configuration.
All of these components are dependent on the same database, which has migrations applied to it. The migrations are applied before the functional tests run, so problematic migrations cause builds to fail. However to discover which Functional tests fail as a result of a migration we have to manually view each one (we currently have 15+ components, and associated TC projects, so it's not ideal).
In order to be able to see the results of all Functional Test configurations in one place, is it possible to aggregate the results of all the Functional Test configurations into a new project WITHOUT creating templates of the current functional test configurations and setting these up in the new project?

Best way to do TDD and CSLA

I would like to know what tools, patterns, etc people have used to be able to do TDD with CSLA .NET 3.8 and higher.
Which parts pose the most effort. Are there parts that are completely untested, etc.
Any and all information is most welcome.
Thanks
I use a combination of SpecFlow with xUnit to test my CSLA business objects. SpecFlow with xUnit are used to define and test the user scenarios (think: functional/acceptance testing), and xUnit alone is used to test individual classes and combinations of such.
Dependencies within the CSLA classes, such as data-access, are injected via a container. Such dependencies can and often are mocked for unit testing.
The test client and our remote Data Portal have separate containers loaded with the correct dependencies. If a test needs to mock any of the Data Portal dependencies we have a special CSLA Command that is executed (via xUnit BeforeAfterTestAttribute) on the Data Portal and replaces standard dependencies with our mocked dependencies. When the tests complete the Command is executed again to put the standard dependencies back into the container.
I hope some of this helps.

Resources