How can I unit-test my database content? - java

We have a case where we are testing a swing application. We have a QA person who up until now was doing manual testing of the app. Now we have realised that manual testing takes a long time to repeat and hence investing time into automated testing of our UI using Fest.
The other side of the coin is testing the database data. Meaning after doing some steps in the GUI, we need to check with the database if the data we expect is present there or not.
Since it's a QA guy who is writing these unit tests for us, we would like to make it as easy as possible for him by providing some sort of framework in order to do this.
Is there some sort of a framework which will test the database against the data that we have? Something like an expected and actual as with JUnit's assert.
Basically we are looking for a framework that has these features:
The 'expected' data should be easy to provide like in a YAML, JSON, Excel Sheet, CSV way. XML and writing code to create beans in java is time consuming.
We would like to create the expected data such that only the columns present in the expected data should be checked against the database.
We don't mind extending the framework to make it easy for a person who doesn't know Java much to work with....

Dbunit looks like a solution for you.
DbUnit can also help you to verify that your database data match an expected set of values.

This seems like a use case for DBUnit

You may also like to consider FitNesse as an easy to use tool. Although you may have to invest more time behind the scenes creating the test fixtures it will be an easy to use tool for the tester. See http://fitnesse.org/

We had a similar situation recently and ultimately went for our own framework. We are basing it on the excellent scala specs library (which can also work with JUnit's runner). The main difference to your case will probably be, that our QA guy has a little programming background and that we write additional more involved test cases within the same framework.
However, to cover you main features, the central idea is to define a domain-specific language for testing your data. This makes it very easy to use for a QA (after the initial overhead for learning how to use the language, what's available for it, etc.).
To more concretely answer your feature points:
Scala works extremely well with XML. No parser code required, boilerplate code is reduced to a minimum. Write the XML-Database-Comparator yourself and provide access to it via the DSL, then the QA can simply write a XML fragment to check for in the database.
Same as above. You provide the comparator yourself, so it's straightforward to ensure this.
Scala works lovely with Java, as it compiles to Java bytecode. You can reuse all your existing Java code for creating the DSL, or even let your test-code access it.
Major advantages for us were that we could reuse the Hibernate datamodel to perform more involved tests on the datamodel, we could still access all our Java code as usual, and the DSL is very easy to read even for non-programmers. (The latter comes in handy, when you try to explain some manager-type what that stuff is actually doing.)

Related

Testing a java jersey application

I have a java/jersey api that is called from the front end. I need to write tests for the java code. How the code is written is:
1. The api call executes the resource method, this calls a separate method that gets data from db and returns to the resource method. This then returns a javax.ws.rs.core.Response to the client.
This is going to be my first time writing tests, so please answer considering I know nothing. What is the best way to start here? And what types of tests should I write. Unit tests are what I’m aiming for here.
Now I have done a lot of research here and I’m leaning towards using JUnit + Mockito to do this. But how do I check for the data in a Response object?
And how should I check the other file that is getting data from db? I found out DBUnit that can do that, but do I need it?
Another framework I came across was Rest Assured. Do I need to include that also? Or can the same things be done with JUnit/Mockito?
I just want some direction from people who have tested out jersey api’s. And want to know what is the most common way to do this.
I do not think there is a best way to do this, what you need to test is often subjective and dependent on the context.
However, you can structure your code in a way that the most important is tested easily and what's left (integration) can be done later / with different tools.
What I suggest here is to follow the principles of the hexagonal architecture. The idea is to keep at the center of your application and without any kind of dependencies (imports ...) to any framework (jaxrs, jpa, etc.) all business rules. These rules can be easily designed with TDD. You will then have very short running tests. It may be necessary to use Mockito to mock implementations of SPI interfaces.
In a second time, you can use this "core" by wiring adapters to the outer world (HTTP, databases, AMQP, etc.), using API and implementing SPI interfaces.
If you want to test these adapters, you exit the scope of unit-tests, and write integration-tests. Integration with a framework, a protocol, anything really.
This kind of tests can use a wide variety of tools, from a framework-related mock (like Jersey test framework), in-memory database (like H2), to fully operational middleware instance using tools like testcontainers.
What is important to remember when writing integration-tests is they are slow in regards of unit-tests. In order to keep a feedback-loop as short as possible, you will want to limit the number of integration-tests to a minimum.
Hoping this will help you!

Why rules engine instead of easily comprehensible one line property?

I am a newbie with the rules engine, so bear with me if this question is very basic. All the tutorials for rules engines have been saying that you can move your business logic outside your code and get it updated by BAs/ end users instead of putting it inside Java code.
I have the following questions
But why can't we write our code to read values from property files and do the same thing?
Also, the rules files seem to have a syntax which is not simply one-liners, compared to .properties files.
Does putting these rules in Rule engine make the code/app work without requiring an app server restart?
3a. If it does NOT, then how can we achieve it?
Had been doing some reading the last few days and I think (it is IMHO), the capacity for allowing business rules to be updated using simple spreadsheets, gives Rules Engines the edge over property files. I can make property files as highly configurable as possible using multiple properties and instructions for modifying rules as comments under each property.
But in a scenario where the business user is able to directly configure the application to apply values based on a "decision table" in a spreadsheet, then that solution will be more desirable.
If any other (budding) developer looking for justification on the for the need of Rule Engines is convinced with this answer, please leave a thumbs up!
If there's a change in logic, you'll change the properties file and deploy the whole project again. Whereas, if you maintain it using BRMS, you can change & test individually on the BRMS only without needing to deploy the whole project again. Once the testing is done and you finally want to deploy the new rule in place, then also, no need to deploy the whole project in production. If you've exposed your rule as API using KIE Server, redeploying just the KIE server would do.
One can write decision tables in such a way that all the logic is contained in the top rows. Then the developer can lock & hide those top rows and then give it to BA. Now BA doesn't see any logic but knows how to maintain the file. Also, not all logics should be written as decision tables.
As I mentioned above, one can deploy each and every rule as a separate rest API and hence is deployable independent of the rest.
In the end, I'd say the main reason we use Redhat BRMS is, as they mention in their documentation,:
Agility: No need to involve developers for a change request. BA's themselves can change the logic.
Visibility: What you see (in the excel) is what you get.
Consistency: Rules are evaluated the same way every time.
Rules engines are not always the answer. However, they provide, in theory, the advantage that the engine can perform complex processing on a simple rule expression and return a result. Other advantages are visibility to the rules and less code.
Answers to your questions.
You can. In simple cases,using property files makes sense.
Rules need to sufficiently complex to cover the business issues they validate. A good rules engine uses a syntax that is readable, even if it is complicated.
In theory, the rules server could run independently of the app server. In large companies, that is normal. The rules server could allow updates without a restart, or it could be restarted (rippled, if there are multiple instances,) without affecting the app server.
Rules engine comes into picture when business users of company want to set certain rules and drive application based on execution results / outcome decisions of rules set. One of examples of such company could be a Law firm or Insurance company where lawyers set rules to drive the quotes calculation for a insurance & rules are subjected to change over period of time. Property file is developer area where business user may not be proficient to make changes. Having separate rules engine tracks the rules and make a business user and a developer work together automating the business seamlessly which could be difficult with properties file.
Rule files syntax is way to convert business rules (verbal) to coding instructions which are executable. Thats where the syntax comes into picture. That way rules engine provide data abstraction to business entities and their relationships.
Integration with rules engine may be done with some broker or a web service or whatever, based on that, server app need rules client jars to make call against. So its matter of deployment and how server picks up changes / hot deploys if rules client jar is updated.
Rules engines are just algorithms for organizing many rules. See the Rete Algorithm.
Basically, it all comes down to complexity. If you have a few simple rules, of course you can use a .properties file. But imagine if some of your rules are 'chained' - one rule affects some other property, which triggers some other rule, which changes another property... you'd have to scan every rule, every change. For thousands of rules, it would take forever. Hence a 'rules engine'.
There are many articles on why you should or shouldn't use a rule engine. Here is one good example.
https://martinfowler.com/bliki/RulesEngine.html

Configuring database development environment along with Hibernate and Spring

We have a web-based application in dev phase where we use Spring 5, JPA(Hibernate) and Postgresql 9.4
Till this moment we were using one instance of the posgresql db for our work. Basically, we don't have any schema generation script and we simply were updating the db if we needed some new table, column etc. For the Hibernate we were generating classes from the db.
Now when we have some amount of test data and each change in the db brings a lot of trouble and confusion. We realized that we need to create and start maintaining some schema generation file along with some scripts which generate test data.
After some research, we see two options
Create two *.sql files. The first will contain the schema generation script the second one SQL to create test data. Then add a small module with a class which will execute the *.sql files using plain jdbc. Basically, we will continue developing and whenever we made some changes we quickly wipe->create->populate the db. This approach looks the most appealing to us at this point. It quick, simple, robust.
Second is to set up some tool which may help with that e.g. Liquibase
This approach also looks good in terms of versioning support and other capabilities. However, we are not in production yet, we are in an active development phase. We don't have much of the devs who do the db changes and we are not sure how frequently we will update the db schema in production, it could be rare.
The question is the following. Would the first approach be a bad practice and applying the second one will give the most benefits and it worth to use it?
Would appreciate any comments or any other suggestions!
First approach is NOT a bad practice, until this generation. But it will be considering the growth of tools like Liquibase.
If you are in the early or middle of the Development Phase, go ahead with LiquiBase, along with Spring Data. Contrarily, in the closing stages of the Development Phase, Think you real need for it.
I would suggest second approach as it will automatically find the new script as you add and execute the script on startup. Moreover, when you have tools available like liquibase and flyway why reinvent the wheel ?.
2nd approach will also reduce the un-necessary code for manually executing the *.sql files. Moreover this code also needs testing and if updated can be error prone.
Moreover 1st approach where you write manual code to execute script also has to check which scripts needs to be executed.. If you already has existing database and you are adding some new scripts you need to execute those new scripts only. These things are taken care of automatically with 2nd approach and you don't need to worry about already executed script being executed again
Hope this answers your concern. Happy coding

TDD without local database?

When we develop a Rails application then we use a local database in our development environment, and make sure that our specs pass as part of TDD.
Is it a norm to not use a local database similar to Sqlite while doing TDD in Java? I have been told in-memory database(HSQL) is all that is needed for running unit and integration tests. Is this a standard practice being followed?
We use Sqlite in our Rails application for local development and for running our Rspecs. But my question is for Java development. We are working on rewritting a part of our application in Java. I have been told that you do not need any database for development if you write integration tests covering all functionality. And have been told that HSQL is sufficient for that. As I am used to having database for local development in Rails, I am wondering how you debug any issues later on? It is quite helpful to analyze any issues if we can replicate the data and scenario in local environment. How do you do same in Java/Spring if you do not use any database for development environment and rely completely on HSQL for testing?
For me, I never use any databases including HSQLDB to write an unit-test.
I prefer to create some interfaces like as: *Repository. and let's the SUT communicate with it. and then I write some implementation class let them implement the interface which I have created. and the classes hierarchy looks like below:
<<uses>>
SUT ---------------> Repository
^
| <<implement>>
|
|--------|--------|-------|
| | | |
JPA Hibernate JDBC .etc
this approach is known as Separation of Concerns. the application domain is a concern, data accessing is another concern. following this approach result in many plug-compatible components and independent modules, such as: domain, jpa, jdbc, and .etc, but the important thing is that will make your test is more testable.
Then I use Test Doubles to mock/stub out its collaboration in unit-test to testing them are work together as expected. the pseudo-code like as below:
repo = mock(Repository.class);
SUT it = new SUT(repository);
when(repo.find(id)).thenReturn(entity);
assert it.exercise() == expectedResult;
assert it.currentState == expectedState;
But you must write some integration test using database to testing each Repository implementation that operate on the third-party api. it is called by Martin: Test Isolation.
The answer to your question: is very common to have your test environment database as close as the development environment as possible.
I suppose that you are preoccupied with performance, there are more crucial things that you could improve before considering having an in-memory database.
Usually while TDD-ing you would only run the tests involved and later run your whole suite to check that you didn't break anything. If you are using Rspec you could use tags.
Another important thing is to clean the database at the beginning of every test since tests should be isolated and never depend on the result of previous tests. This will improve complex search queries that you could have in your system. there is a gem that could help you here.
Finally, if you are using some sort of continuous integration tool remember to set it up using rake db:schema:load instead of rake db:migrate. This will run your schema file as a single migration instead of running each single migration every time you commit. (Remember to keep this version-controlled and always up to date)
You are getting terminology wrong. TDD is about writing test cases in general. But most of the time, and also in your question, one thinks about using TDD for unit testing.
And unfortunately, terms are not very clear. When you turn to wikipedia, you find there (my words): "anything you do to test a piece of software" can be called a unit test.
But that isn't helpful. You should rather look for definitions such as here. And the main aspect there: unit tests work in isolation. Quoting from that link:
Runs in memory (no DB or File access, for example)
Thus:
when doing unit testing, you should not use any database
when you integration tests, you want to ensure that your solution works "end to end". In that sense you might be using a special instance of your database, but not a different kind of database.

How do I test a component were the output goes to a database using Cucumber?

Recently there was a discussion in my team about how to properly test a component of our system where the output is stored in a database. We use DDD to create our system so the component ultimately talks to a repository that has different stores implemented to talk to a MongoDB. As testing framework we use Cucumber and the database we use for testing is an in-memory version of mongo.
Up until now, all our scenarios had a command as input and the output was an event so our assertions were done on the event. But now we have a scenario where the event is processed and the result is stored in a database. The result can be retrieved using a rest call after that happens.
The discussion was about the way to test these two last scenarios. For some, the correct way is to check the in-memory database after the event is processed because that's the output of the system. The ultimate part of the system are the stores and they have to be tested as well as part of the scenario. Testing what the in-memory database contains is the right way as the stores are still using the same production ready logic to write the output. For convenience, we would use the repositories to retrieve this data as is easier this way, even when we need to use something not related to the scenario at hand.
On the other hand, for some people we shouldn't be checking the database as that's another component which we shouldn't be accessing for the test. Instead, because in this case the rest call is just retrieving the data, we should use the rest call as part of the test to verify the output. This way, our scenario would include this 2 parts, the storing and the retrieving instead of splitting the tests.
Is there any correct answer to this? Are we missing any point here?
Thanks.
I'd say verifying with a REST call is the correct way to do it here. Otherwise it wouldn't really be blackbox testing, and your test will depend on internal implementation details (your database structure). You usually want to see what effect your application has on the "outside world", and your database is not part of this IMO.
This is all assuming the tests you are creating are intended to be blackbox tests. If it's an integration test (~grey box I guess?) then IMO checking the database using the repository is probably a better idea.
If it's intended to be a unit test, the dependencies of your component should be mocked. You can then use the mocks to verify that your component called the repository correctly.
If I misunderstood something, do let me know. :)

Categories

Resources