I'm currently debugging some fairly complex persistence code, and trying to increase test coverage whilst I'm at it.
Some of the bugs I'm finding against the production code require large, and very specific object graphs to reproduce.
While technically I could sit and write out buckets of instantiation code in my tests to reproduce the specific scenarios, I'm wondering if there are tools that can do this for me?
I guess specifically I'd like to be able to dump out an object as it is in my debugger frame (probably to xml), then use something to load in the XML and create the object graph for unit testing (eg, xStream etc).
Can anyone recommend tools or techniques which are useful in this scenario?
I've done this sort of thing using ObjectOutputStream, but XML should work fine. You need to be working with a serializable tree. You might try JAXB or xStream, etc., too. I think it's pretty straightforward. If you have a place in your code that builds the structure in a form that would be good for your test, inject the serialization code there, and write everything to a file. Then, remove the injected code. Then, for the test, load the XML. You can stuff the file into the classpath somewhere. I usually use a resources or config directory, and get a stream with Thread.currentThread().getContextClassLoader().getResourceAsStream(name). Then deserialize the stuff, and you're good to go.
XStream is of use here. It'll allow you to dump practically any POJO to/from XML without having to implement interfaces/annotate etc. The only headache I've had is with inner classes (since it'll try and serialise the referenced outer class).
I guess all you data is persisted in database. You can use some test data generation tool to get your database filled with test data, and then export that data in form of SQL scripts, and then preload before your intergration test starts.
You can use DBUnit to preload data in your unit test, it has also a number of options to verify database structure/data before test starts. http://www.dbunit.org/
For test data generation in database there is a number of comercial tools you can use. I don't know about any good free tool that can handle features like predefined lists of data, random data with predefined distribution, foreign key usage from other table etc.
I don't know about Java but if you change the implementations of your classes then you may no longer be able to deserialize old unit tests (which were serialized from older versions of the classes). So in the future you may need to put some effort into migrating your unit test data if you change your class definitions.
Related
I'm working on a legacy project that have many external dependencies and classes are so tightly coupled that it's almost impossible to unit test. I know the best way to address this would be doing a major refactor but at the moment we do not have the luxury to do so as the project is virtually 0 tests so we are very concerned about breaking stuffs.
What we are trying to achieve at the moment is to quickly come up with unit / component tests and progressively refactor as we work on the project. For component test I'm thinking to have some kind of wrapper on the existing classes to 'record' the input and output then persist it to a physical file. When we are running tests then it will return output based on the input.
How I'm thinking to achieve that is to store the method name and input parameters as the key and the output as the value. And output will be serialized upon 'record' and deserialized during test.
This approach seems to be able to cater for some cases.. but I foresee there will be a lot of complications later on. Eg: I might face several issues serializing certain objects. And I might also experience difficulties passing object reference from "out" parameters.
So here comes my question. Is there any libraries that does all these things? I would have never considered doing this manually if there was a library for it. By the way I'm using Java.
Thanks
Instead of doing low level unit tests, I would start with tests for the minimum units you can divide now, i.e. possibly just one. You can capture the data input and out using a serialization library which doesn't require the objects be marked as Serializable e.g. Jackson.
Suppose I want to write a test(s) for a Java class that would provide a method for reading and parsing external files (to be precise, files would be JSON and I would be using Jackson).
Moreover, I've got some examples of JSON files I'd parse, and I also have a vague idea what kind of Java object this SomeMagicalReader.readPony("path/to/location/pony.json") method should return; if I manage to getreadPony to return a some kind of PonyObject, I think have an idea how to test that the produced PonyObject is what I expect.
The question I have concerns providing the readPony function with the test data. I'm probably thinking about this way too much, but (1) is there an idiomatic "Java + Junit" way of doing that? (= testing a method that reads external files?) Copypaste the contents of the example file as a String variable in the test code? (They're fairly short, but that would still end up looking ugly quite fast.) Place the example JSONs just ...somewhere and call readPony with the path? (This sounds more sensible.) (2) What would then be a canonical place to put such external JSON test files, if my tests are organized in a Maven style test package hierarchy, e.g. src/test/java/com/stuff/app/package/SomeMagicalReaderTest.java?
As per maven's standard directory layout, I would advise you to put you JSON test files in src/test/resources since they are test resources. Note that you can (and should) organize your own folders hierarchy under the resources folder (other developers would find it easier to locate specific test resources when fixing or adding some other tests).
So yes you would end up with your JSON files somewhere but not anywhere if your own test resources hierarchy is good enough (for example, if you think your package structure is well organized with meaningful package names, following it for your test resources hierarchy isn't a bad idea at all).
You should ask yourself what the mission critical code is for your project - reading files or parsing their content. For my projects, parsing was the interesting part, so I placed files to parse as test resources, read them in the unit test to string and pass them to the parser to unit test the parser. It is also possible to include the contents directly in unit tests as big ugly strings, but when you have a dedicated place for test resources, why not use it.
Copypaste the contents of the example file as a String variable in the test code
I suggest against doing this as it makes modifying the input for your tests more difficult. Also, using an external file makes your tests more flexible. For example, reading an external file allows you to create multiple tests while reusing the basic framework for each test. Of course, this also means that you will need to take some time to design the methods that actually perform the tests.
Hello all :) In the JVM debug mode you can inspect the objects that are present when you run your code.
This means one can create a utility that can generate a dump of those objects as ready to use mocks (or close enough, hopefully). Those mocks would span the entire scope of the program run, and this would help greatly in building an extensive test coverage.
Because lazy is good, I was wondering if such a utility is currently available.
Best regards
I don't know of a way to do this from a memory/heap dump or from debug mode but...
If you want to serialize arbitrary java objects to and from files for use in tests then you can use XStream to do so. You could then use them in your unit tests with ease.
You can also use standard Java serialization if your objects are all serializable.
To collect the data in the first place you can create an aspect using AspectJ or Spring-AOP or similar. I've done something similar in the past and it worked really well.
One word of caution though: If you are doing this then any refactoring of your objects require refactoring of the test data. This is easier with XStream as it's XML files you are dealing with.
I had written a lot of java bean classes using my IDE. Another person suggests a different approach. He suggests that I put an xml file with bean definitions in them. Then I either use jaxb or xslt to dynamically generate the classes during build time. Though its a novel and interesting approach, I do not see any major benefit in it.
I see only one benefit in this suggested approach : The java bean classes need not be maintained in configuration control. Any bean changes is going to require only an update in the xml file.
Are there any major benefits in dynamically generating java classes ? Is there any other reason why this approach is taken ?
I agree with #Akhilss. My experiences have been in large scale Java EE projects where code generation is common.
It all depends on your project. If you are coding only a few beans and only need basic functionality then I don't see the need to start with XML (Which is often over used anyway). Especially if you actually don't need the XML as well.
However if you are building a system which needs the XML, an example being a SOAP web service WSDL and schema, then generation is a good idea because it saves you from manually keep schemas and beans in sync. As well as providing factory classes and other support code.
As a counter argument, with EJB3 and similar standards, it's now often easier to write the beans and generate the messy XML stuff on the fly. Ie. let the server do the grunt work.
Another reason to consider code generation is if you require more complex functionality in your beans because they represent data structures. A few years ago I trialled the Apache Tuscany project for generating SDO beans from XML. The nice thing about that was that I could generate functionality like property change notifications so when I modified any of the bean's properties (including collections), other parts of your program could be notified automatically. Generated functionality like that can save you a lot of time and money if you need it.
Ultimately, I'd suggest adhering to the KISS principle. So don't add what you don't need. Generated code from XML is useful if it helps you in the long run. But like any technology, be sure you are adding it for the right reasons.
I have used Jibx and its generator in my project. My experience has been mixed.
The usual case for using JAXB's (XJC) generator is referred to in http://static.springsource.org/spring-ws/site/reference/html/why-contract-first.html
Conversion to and from XML maked it possible to store in the DB and retrieve for future use as well as use for test case input for functional tests.
Using any kind of generator (Jaxb,Jibx,XMLBeans,Custom) might make sense for large sized projects. It allows for standardization of data types (like BigDecimal for financial amounts, like ArrayList for all lists), forcing interfaces (like Serializable or Cloneable). This enforces good practices and reduce the need for reviews of generated files.
It allows for injection of code through XSLT or post processing of generated java file. Example is to inject Rounding code to a specific decimal size(2,6,9) with a specific policy (UP,DOWN,NEAR) within the setter method for each field of type financialAmount. Forcing such behavior does reduce the instance of bugs(for incorrect financial values which companies are liable for).
The disadvantage are
Usually each java class can be only a bean class. Any customization made will be overwritten. Since (in my case) the generator is tied in to the build process. The classes get generated with every build.
You cannot do implementation of your custom interfaces on a bean class or add annotations for your own or third party frameworks.
You cannot easily implement patterns like a factory method since default constructors are usually generated. Refactoring is usually difficult since generators do not usually support it.
You may(not sure now, was true a couple of years ago for Jibx) not be able to generated ENUMS when it would be most applicable.
You may not be able to override the default datatype with your own regardless of the need. CopyOnWrite list and not ArrayList for a variable shared across threads or a custom implementation of a List which also implements the Observer pattern.
The benefits of a generator outweigh the costs for large sized (in persons and not code, think 150 developers in three locations) distributed projects. You can work around the disadvantages by defining your custom classes which contain the bean and implements behaviour or post processing (adding additional code) with further metadata picked up from XSD annotations or another configuration file. Remember support and Maintenance of the generator become critical since the entire project depends on it. Use it with CAUTION.
For smaller sized projects I personally would write my own classes. For larger sized projects I personally would not use it in the middle tier mostly because of the lack of refactoring support. It can be used for simple beans meant to be bound to UI frameworks.
Here's the scenario. I have VO (Value Objects) or DTO objects that are just containers for data. When I take those and split them apart for saving into a DB that (for lots of reasons) doesn't map to the VO's elegantly, I want to test to see if each field is successfully being created in the database and successfully read back in to rebuild the VO.
Is there a way I can test that my tests cover every field in the VO? I had an idea about using reflection to iterate through the fields of the VO's as part of the solution, but maybe you guys have solved the problem before?
I want this test to fail when I add fields in the VO, and don't remember to add checks for it in my tests.
dev environment:
Using JUnit, Hibernate/Spring, and Eclipse
Keep it simple: write one test per VO/DTO:
fill the VO/DTO with test data
save it
(optional: check everything has been correctly save at the database level, using pure JDBC)
load it
check that the loaded VO/DTO and the original one matches
Productive code will evolve and tests will need to be maintained as well. Making tests the simplest as possible, even if they are repetitive, is IMHO the best approach. Over-engineering the tests or testing framework itself to make tests generic (e.g. by reading fields with reflection and filling VO/DTO automatically) leads to several problems:
time spent to write the test is higher
bug might be introduced in the test themselves
maintenance of the test is harder because they are more sophisticated
tests are harder to evolve, e.g. the generic code will maybe not work for new kinds of VO/DTO that differ slightly from the other and will be introduced later (it's just an example)
tests can not be used easily as example of how the productive code works
Test and productive code are very different in nature. In productive code, you try to avoid duplication and maximize reuse. Productive code can be complicated, because it is tested. On the other hand, you should try to have tests as simple as possible, and duplication is ok. If a duplicated portion is broken, the test will fail anyway.
When productive code change, this may require several tests to be trivially changed. With the problem that tests are seen as boring piece of code. But I think that's the way they should be.
If I however got your question wrong, just let me know.
I would recommend cobertura for this task.
You will get a complete code coverage report after you run your tests and if you use the cobertura-check ant task you can add checks for the coverage and stop the ant call with the property haltonfailure.
You could make it part of the validation of the VO. If the fields aren't set when you use a getter it can throw an exception.