1

Is there a Java test library which supports the following scenario?

Assume, you have to write web browser tests for a database-based web application (e.g. using Selenium) . A typical test will have the following workflow:

  • Insert test data to DB
  • Run the test logic (open web browser, navigate somewhere, manipulate something, validate if correct things are displayed, validate if DB state changed correctly)
  • Clear the DB

Especially in case of this kind of integration test, you often will require a complex set of diverse objects just to just run the web application (e.g. you need a user account, business-related stuff like products, oders, ...). To keep the tests independent of each other and being able to run the tests in parallel, you want to create this object network for each test, probably with pseudo-random object attributes like user.name="user_123".

Now, in my opinion, a good place to do things you have to repeat for each test, is a @Before-annotated method. However, if the @Before method inserts a DB state, the test method won't know how to access this state, e.g. how to find the user object the @Before method created. It would be nice to have a kind of test method context, which is setup by the @Before method and can be used by the test method.

I thought about implementing something like this on my own, maybe a simple static hashmap with the test method name as key, but probably there already is a library which provides this feature and you know about it ;-) .

rainer198
  • 3,195
  • 2
  • 27
  • 42
  • 1
    I do not get your scenario. You want your test to run independently and parallely. The code within `@Before` is run before each and every test. So only test datas that are common for all tests you can create in `@before` method. why can't you create all other test data that are very specific to individual test within the test method itself? – thiyaga Jan 08 '14 at 08:17
  • Because, even if the _common_ data is not subject of a particular test, it might be influenced by a test method. Think about the user account and two tests: 1) a test which (as a side effect) causes the user account to be deactivated and 2) a test creating an order. If both tests would rely on the same user object, the tests wouldn't be independent although the user object is not the topic of these tests. Thus, I would like to have distinct user account objects but do not want to repeat the creation in each test (even not by a helper method). That's why I want to use the @before method – rainer198 Jan 08 '14 at 08:24

2 Answers2

1

You are practically there. In fact, we use the exact same technique for integration tests in our product (HP ALM).

In your test class, store whatever tokens generated by the @Before method in members and use them in the tests.

In order not repeat this for each and every integration test class, we defined a base class that contains all the context and the initialization logic and we simply extend with test code.

This base class can in tern extend any other test infra that you may be using (such as AbstractJUnit4SpringContextTests).

Vitaliy
  • 8,044
  • 7
  • 38
  • 66
0

rainer198, instead of "Clear the DB" you can rollback the tx. I use this way to solve the issue, it is more clean, but, obviously, it depende from your behavior.

On spring I use

@Transactional //This annotation tells the Spring test runner to always roll back each transaction it creates.
@TransactionConfiguration(defaultRollback = true)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/spring/common-main-test.xml")
venergiac
  • 7,469
  • 2
  • 48
  • 70
  • Thought about this, too. But does it really work in my integration test scenario? Notice that I have two transactions: The one of the test method and the one within the deployed web application the test is running against: The application would not see the test data as long as the test transaction is not committed, right? – rainer198 Jan 08 '14 at 08:29
  • Yes, it cannot see! Howevere, you can set the isolation level (just for test) to Read uncommitted in ordre to allow DIRTY READ. – venergiac Jan 08 '14 at 08:45
  • OK, but then I end up in dirty test dependencies again ;-) – rainer198 Jan 08 '14 at 08:49
  • mhhhh, yeap! I think that you are using Unit Test to do integration test which is not properly (but commonly done) correct. You can try Arquillian – venergiac Jan 08 '14 at 09:03