Software Testing
Basics and integration testing of J2EE applications
EAM/EDMS development workshop 02/08/2024 EDMS 1884325 2
Software Testing
Basics and integration testing of J2EE applications
EAM/EDMS development workshop 02/08/2024 EDMS 1884325 3
What do we mean by testing?
• Software testing has many flavors: unit
testing, integration testing, functional testing,
stress testing, black/white box, monkey
testing...
• Not all tests are created equal
• The basic purpose of tests is to provide
verification and validation of software
02/08/2024 Document reference 4
Validation versus verification
• Verification: did we build the software right?
Does it fulfill its original requirements?
• Validation: did we build the right software?
Does the project meet the users’ needs?
• Unit, integration tests, static analysis provide
verification
• User acceptance tests (UAT) provide
validation
02/08/2024 Document reference 5
Code coverage
• One of the measures used for systematic
software testing
• Tries to answer the question: how much of
my code is run in my tests?
• The assumption is:
the more code is executed
the smaller the chance is of a bug emerging
02/08/2024 Document reference 6
Code coverage
• Of course, a 100% code coverage doesn’t
mean 100% working software
• A talented developer can have multiple bugs
in fully covered code – the construction of
the test cases matters
02/08/2024 Document reference 7
Test Driven Development (TDD)
• A methodology of developing code which is
based on writing tests first
• The TDD mantra is:
red green refactor red...
02/08/2024 Document reference 8
02/08/2024 Document reference 9
Pros and cons
• Forces modularity and • Tests can be hard to
testability of the code write
• Induces confidence among • Adds a layer of
team members (even if complexity which needs
you break something, the
to be maintained
tests will let them know)
• Gives false confidence if
• Obvious mistakes are
harder to commit the test is badly written
• Forces good code
coverage
Conclusion: TDD is good Conclusion: TDD is bad
02/08/2024 Document reference 10
Unit tests
• Low-level
• Usually testing one method/class, ideally
limiting dependencies on other
methods/classes and components
02/08/2024 Document reference 11
Integration tests
• Take into account the broader context of the
application (database, external APIs, filesystem,
concurenncy
• Verify that the – ideally unit tested - building
blocks (methods, classes, modules etc), work
well together.
• Unlike unit tests, which should run at build-time
and should be very quick to run, integration tests
require a deployment step
• Usually will touch significantly more code than
unit tests
02/08/2024 Document reference 12
Humor
02/08/2024 Document reference 13
Integration tests in practice
• Java EE or Spring applications can make
heavy use of dependency injection or other
container services
• Whether an application works well within the
container is crucial, since the containter
provides the implementation for the services
defined e.g. in the JEE standard
• The system configuration is equally as
important (have we moved everything from
DEV to TEST?)
02/08/2024 Document reference 14
Arquillian
• De facto industry standard for J2EE
integration testing; also works with Spring,
although it’s not as popular
• Allows to run integration tests within the
context of a fully configured application server
as a build step
• Arquillian Warp is an extension which allows
to use a client-side testing framework and to
inspect server state at the same time
• Works well with Junit
02/08/2024 Document reference 15
Arquillian test
1. Start an instance of the container
2. Deploy an archive to the server.
3. Run the test cases (JUnit/TestNG integration)
4. Undeploy the archive and kill the instance.
The configuration of the application server is preserved.
Running the test on a running instance of a server is as
simple as
mvn clean test
including the deployment and undeployment of the test
package.
02/08/2024 Document reference 16
How a test is written
02/08/2024 Document reference 17
Let’s dissect it...
This JUnit annotation tells
the engine to use a
different runner than the
default
This annotation specifies
the deployment archive for
Arquillian
Using ShrinkWrap to package our classes into a web archive
It’s also possible to use a Maven dependency resolver – no need to specify
any classes or packages, they are read from the pom.xml
02/08/2024 Document reference 18
Let’s dissect it... Ordinary EJB annotation
to lookup a bean in JNDI
Standard JUnit syntax!
02/08/2024 Document reference 19
Also possible with Spring...
Nice showcase:
https://github.com/arquillian/arquillian-
showcase/tree/master/spring
02/08/2024 Document reference 20
Surely it takes long!
This time includes the packaging, deployment, running the aforementioned
tests and undeploying the package.
02/08/2024 Document reference 21
Arquillian Warp
• „Fills the void between client-side and
server-side testing”
• Allows to mock client-side actions in order to
inspect server state
• Can be used with e.g. Selenium WebDriver
• Example coming….
02/08/2024 Document reference 22
02/08/2024 Document reference 23
Arquillian
• Configuration is somewhat non-trivial and is
done in XML files; however, for J2EE
projects there are archetypes which provide
Arquillian support „out of the box”
• Sharing the project among team members
requires to set an environmental variable
• Can be run with maven test - easy to
integrate into a Maven build
02/08/2024 Document reference 24