How to avoid database auto clear when running Play Framework test? - java

I want to run serveral unit test and functional test on my Play Framework App(Play 1.4.0). A Test class like:
public class StatisticTest extends UnitTest {
#Test
public void testOutputStatistics() {
//code
}
}
And I have some data in my database which the test class need to read. But the Play test will clear all data in the database automatically. I have to import my data via SQL by using Fixtures.executeSQL() every time. This lowers the efficiency. So I want to know how can I avoid this auto clear.

In application.conf, set the test.jpa.ddl as "update" rather than "create".
%test.jpa.ddl=update

Related

Testing conditions and exceptions in Integration Tests?

I have written several Unit Tests and now switched to write Integration Test in our Java (Spring Boot) app. We use JUnit and Mockito libraries for testing.
As far as I know, Integration Tests check the entire rings rather than a function. However, I am confused that if I should also check the if conditions in the methods while integration testing. Here is an example service method:
#Override
public CountryDTO create(CountryRequest request) {
if (countryRepository.existsByCodeIgnoreCase(countryCode)) {
throw new EntityAlreadyExistsException();
}
final Country country = new Country();
country.setCode("UK");
country.setName("United Kingdom");
final Country created = countryRepository.save(country);
return new CountryDTO(created);
}
My questions are:
1. Can I write integration test for a Service or a Repository class?
2. when I test create method in my service above, I think I just create the proper request values (CountryRequest) in my Test class, then pass them to this create method and then check the returned value. Is that true? Or do I also need to test the condition in the if clause (countryRepository.existsByCodeIgnoreCase(countryCode))?
3. When I test find methods, I think I should first create record by calling create method and the proper place for this is #BeforeEach setup() {} method. Is that true?
If you wrote Unit tests that made sure, your services and repositories are working correctly (for example by validation and parameterized tests) I believe, you don't have to write integration tests for them.
You should write integration tests to check the behavior of your app. By testing if your controller is working correctly you will also check if service and repo are ok.
I believe unit test should check it.
Do you ask if you should create record in db? If you want to test if repository is correctly communicating with service and it with controller, you have to do it with some data.

Debugging ignored tests in testng?

I have a maven Java project in Intellij IDEA community. The TestNg version is very old i.e. 6.9.5 and I simply cannot update it. I have 6 TestNg test methods in a class. Only 5/6 of these methods use data provider methods, all of which are in one DataProvider class.
When I run the test class, only the method without data provider (say test_5) runs successfully. The others are marked as "test ignored". Moreover, when I comment or disable test_5, then all the other tests run. Can I make testng give a detailed reason for ignoring tests ?
Here is brief information about my project. I can't give the full code.
public class MyUtilityClass {
public class MyUtilityClass(){
//Load data from property files and initialize members, do other stuff.
}
}
public class BaseTest {
MyUtilityClass utilObj = new MyUtilityClass();
//do something with utilObj, provide common annotated methods for tests etc.
}
public class TestClass extends BaseTest {
#BeforeClass
public void beforeMyClass(){
//Get some data from this.utilObj and do other things also.
}
#Test(dataProvider = "test_1", dataProviderClass = MyDataProvider.class)
test_1(){}
#Test(dataProvider = "test_2", dataProviderClass = MyDataProvider.class)
test_2(){}
...
//test_5 was the only one without data provider.
test_5(){}
#Test(dataProvider = "test_6", dataProviderClass = MyDataProvider.class)
test_6(){}
}
public class MyDataProvider {
MyUtilityClass utilObj = new MyUtilityClass();
//do something with utilObj besides other things.
}
Your tests need to end in exactly the same environment in which they started.
You gave nary a clue as to what your code is like, but I can say that it is almost certainly either a database that is being written to and not reverted or an internal, persistent data structure that is being modified and not cleared.
If the tests go to the database, try enclosing the entire test in a transaction that you revert at the end of the test. If you can't do this, try mocking out the database.
If it's not the DB, look for an internal static somewhere, either a singleton pattern or a static collection contained in an object. Improve that stuff right out of your design and you should be okay.
I could give you more specific tips with code, but as is--that's about all I can tell you.
I solved my problem. Test_5 is the only test method which does not have a data provider. So, I provided a mock data provider method for it.

Parametrized Junit tests with Serenity reports

I ran into some trouble testing a Spring app. The current approach in my team is to write scenarios in Gherkin and have Serenity provide its pretty reports.
A new component in the app will need a lot of test cases. The requirements will be provided in a few 'parsable' excel files so I thought it would be neat to just use them directly, row by row, in a Junit parametrized test. Another option would be to write a bloated Gherkin feature and tediously compose each example manually.
So I thought of something like that:
#RunWith(Parameterized.class)
private static class Tests {
#Parameterized.Parameters(name = "...") // name with the params
public static Collection params() {
// parse excel here or use some other class to do it
}
#Test
public void test() {
/* do the actual test - it involves sending and receiving some JSON objects */
}
}
This works smoothly but I ran into trouble trying to use
#RunWith(SerenityRunner.class)
The problem is that Junit does not support multiple runners. A solution I found is to make a nested class and annotate each with a different runner, but I don't know how to make it work (which runner should be on the outside, where do I actually run the tests, an so on).
Any thoughts?
Actually Serenity provides another runner - SerenityParameterizedRunner which seems to have the same features as JUnit's Parameterized.

Spring Junit Database rollback at the end of test class

I have a lot of existing Spring JUnit tests.
All this tests extends an abstract test class.
public class ServiceTest extends AbstractServiceTest {
But in this abstract class we reinitialize the database. So it will reinitialize the database on each test class
#Before
#Override
public void initGlobal() throws Exception {
initDatabase();
... }
I am asking how I can do a rollback on a test class in the end of execution of its tests ? So i can initialize a database one time and rollback changes in every test class
I think having two profiles is a better option one for testing and other one for development and on the testing profile use memory based database like H2 (here is a good example) and on your development profile use your main database
When running the tests use the testing profile.Instead of doing rolling back or deleting data each time you run your test
If you want to use a real database in unit tests that I totally discourage it.You can use the spring test runner to annotate your class and rollback transactions
#RunWith(SpringJUnit4ClassRunner.class)
#TransactionConfiguration(defaultRollback=true)
public class YourTestClass {
#Test
#Transactional
public void myTestMethod() {
// db will get rolled back at the end of the test
}
}

How do I create pre-formatted Java files in Eclipse?

I am currently writing JUnit test cases using the Selenium-RC API. I am writing my scripts like:
//example JUnit test case
public class myScripts extends SeleneseTestCase {
public void setUp() throws Exception {
SeleniumServer newSelServ = new SeleniumServer();
newSelServ.start();
setUp("https://mySite.com", "*firefox");
}
public void insert_Test_Name throws Exception {
//write test code here
}
}
And for each test, I have a new JUnit file. Now, since the beginning of my JUnit files will all basically be the same, just with minor variations towards the end, I was thinking about creating a pre-formatted Java template to write create a file with the redundant code already written. However, I can't find any information on whether this is possible. Does Eclipse allow you to create file templates for certain packages?
Create a super class to add all the common code. Creating template is really bad because of the fact you are duplicating the code at the end of the day.
class Super extends SeleneseTestCase{
// Add all common code
}
class Test1 extends Super{
// only special test case logic
}
Also I would suggest not to create SeleniumServer instance for each test case, It will reduce overall performance of the test suite. You can reuse object as long as you are running test sequentially.

Categories

Resources