Discussions

News: Container Driven Testing Part II: Testing Entity Beans

  1. Container driven testing lets you write more isolated, fine-grained and robust unit tests. Using code samples, N. Alex Rupp covers techniques and strategies for testing your Entity Beans. Entity Beans come with their own special considerations and issues, because in addition to the bean classes and the test cases, you must also concern yourself with generating a database.

    Read Container Driven Testing Series - Part II: Testing Entity Beans
  2. Container Driven Testing[ Go to top ]

    The problem that Alex poses is roughly this. Tests normally runs on the client, the container normally runs on the server. How do you get things to run together seamlessly.

    Alex's proposed solution is to pull the container down to the client.

    The approach that I have had a lot of success with is to push the tests to the server. My Ant script deploys a JunitEE war file, with my tests, to the server, and runs the test in-container via an HTTP request.

    The code of my tests looks just like the code Alex publishes using in his approach.

    The advantage of deploying the tests into the server is that you can actually test on the same type of container that you will be using in production. It appears that Alex's approach locks you into OpenEJB as a test environment.

    As a bonus, JunitEE provides a nice interactive interface if you want to quickly run selected tests.
  3. Container Driven Testing[ Go to top ]

    The approach that I have had a lot of success with is to push the tests to the server. My Ant script deploys a JunitEE war file, with my tests, to the server, and runs the test in-container via an HTTP request.
    I don't see a problem with this approach, either. I think it would be especially helpful for running integration tests. I'm all for it, so long as the components are being tested in a real container. The only problem I can forsee with it is that it might slow down development quite a bit to have to deploy the app into a web container. I might use a combination of these two approaches. Embedded container during development, running application in pre-production/QA. What do you think?

    Regards,
    --
    Alex
  4. Container Driven Testing[ Go to top ]

    My Ant script deploys a JunitEE war file, with my tests, to the server, and runs the test in-container via an HTTP request. The code of my tests looks just like the code Alex publishes using in his approach.
    It appears that Alex's approach locks you into OpenEJB as a test environment.
    You were right in the first statement where you mention the tests are just ordinary tests. You could easily run the same tests via JunitEE.
    The advantage of deploying the tests into the server is that you can actually test on the same type of container that you will be using in production.
    JunitEE is a pretty good tool. I've used it and like it quite a bit. The value add of Container Driven Testing tools like OpenEJB or JunitEE is that they don't tie you into the container or environment at all and all.

    A perfect scenario would be:

      Development -- run your test cases from Maven or Ant with an embedded OpenEJB serving the container functionality. Very fast and cuts down on the deploys you have to wait for during the day.
     
      QA and Production -- Use JunitEE to run the same tests in the production container by deploying the code and tests and sending an HTTP request to the JunitEE servlet. Not very fast, but who really cares as this only happens once in a while, not several times a day.
      
    I would probably do the QA test nightly or at least once a week, not just before a production push.

    Now that aside, there is one thing that the embedded OpenEJB container approach to Container Driven Testing gives you that the JunitEE approach to Container Driven Testing can't give you. JunitEE is a servlet and requires a servlet container to run. When testing with and embedded OpenEJB, your tests are run as plain JUnit tests.

    So you can run the tests from say Eclipse in debug mode and step from the testing code all the way into your enterprise bean code.
  5. Testing servlets[ Go to top ]

    JunitEE is a servlet and requires a servlet container to run. When testing with and embedded OpenEJB, your tests are run as plain JUnit tests. So you can run the tests from say Eclipse in debug mode and step from the testing code all the way into your enterprise bean code.
    Which raises a question I've asked myself recently--when can we expect to be able to test in this way with servlets? Maybe someday with Jetty?

    --
    Alex
  6. Testing servlets (p.s.)[ Go to top ]

    when can we expect to be able to test in this way with servlets?
    I don't think "expect" is quite what I meant here. I don't really expect anything, but one certainly can dream. I would love to be able to test my servlets in a manner similar to this one. Until then, here's to mock object testing and avoiding servlets whenever possible!
  7. Testing servlets[ Go to top ]

    Which raises a question I've asked myself recently--when can we expect to be able to test in this way with servlets? Maybe someday with Jetty?--Alex
    Hi Alex,

    Yes, it's possible. See http://jakarta.apache.org/cactus/integration/integration_jetty.html

    -Vincent
  8. Container Driven Testing[ Go to top ]

    JunitEE is a servlet and requires a servlet container to run. When testing with and embedded OpenEJB, your tests are run as plain JUnit tests.
    Hmmm, some people might argue that a servlet container is not as heavy a dependency as an EJB container.
    So you can run the tests from say Eclipse in debug mode and step from the testing code all the way into your enterprise bean code.
    I am able to do the same thing with JunitEE and a remote debugger.

    If you have prohibitively long deploy cycles, then I can see advantages to using the embedded container. But this hasn't been a big issue for me.
  9. Container Driven Testing[ Go to top ]

    What if your application is not a web app?
  10. Container Driven Testing[ Go to top ]

    JunitEE is a servlet and requires a servlet container to run. When testing with and embedded OpenEJB, your tests are run as plain JUnit tests.
    Hmmm, some people might argue that a servlet container is not as heavy a dependency as an EJB container.
    I didn't really make that argument. Jetty is a wonderfully light servlet container, for example. Just making a concrete distinction between how the actual tests are run. When the test are just run as plain tests, they can be run from any tool with Junit support.
  11. Typo[ Go to top ]

    Hi,
    The self-referential link near the top of the page bears the title "Testing Session Beans" instead of "Testing Entity Beans".
  12. Hi,
    This article talks mostly about testing the CRUD operations and transaction management that are performed by entity beans. But isn't that one of the main reason of using CMP? Because you trust the EJB container to do it right for you. It makes no sense to test the CMP implementation of a container, because most certainly it has been extensively tested before.
    When testing an entity bean, it would make more sense to test the domain specific methods (if there are any). By this I mean testing methods like computeLoanRate(), deposit() kind of methods.
    Best regards, Mircea
  13. This article talks mostly about testing the CRUD operations and transaction management that are performed by entity beans. But isn't that one of the main reason of using CMP? Because you trust the EJB container to do it right for you.
    I agree.

    The CRUD tests they are talking about is something I consider to an integration test and then I would use Cactus. Personally I think it's easy to unit test functionality placed in entity beans. The reason is that all the getters and setters are abstract and I can mock these implementation. The problem is when I need to test something like:

    ctx.setRollbackOnly()

    But again this might be more suitable to consider as integration test.

    Personally I think that if you don't have any self-written functionality within Entity Beans (uses Entity Beans only for getting and setting data), use a integration test tool like Cactus and focus on testing the Session Facade.
  14. Setting up and tearing down the database data for unit testing often is so expensive and complicated that it prohibits a fast Test Driven Development approach.

    We have had much more luck mocking out of the persistence layer and concentrating unit testing in the business layer. We then carry out more complicated integration testing towards the end of the development cycle.

    David
  15. The CRUD tests they are talking about is something I consider to an integration test and then I would use Cactus.
    There is definite synergy between Cactus and OpenEJB. Please don't get the impression that it's a one over the other decision. The article mentions using bare unit tests with Maven, but you can easily add Cactus to the picture.

    The advantage of using Cactus with OpenEJB is that you could cut out server start/stop and undeploy/redeploy times. You would be looking at millisecond times rather than seconds. That would be a good way to go for the daily grind. With Cactus it would be just as easy to run the same tests against the QA or production environments.
    Personally I think it's easy to unit test functionality placed in entity beans. The reason is that all the getters and setters are abstract and I can mock these implementation. The problem is when I need to test something like:

    ctx.setRollbackOnly()

    But again this might be more suitable to consider as integration test.
    I know what you mean as it's the final resource that carries out the actual rollback. But there are API rules associated with all transactional methods that can easily be broken and should be tested.

    For example, I can't tell you how many times I've seen people use Required as the transaction attribute of a finder method when they are not calling the finder from within a transaction. The finder will successfully run as the container will automatically begin TX before the finder then commit the TX after the finder returns, but the enumeration returned will only be valid inside the transaction which already completed. Any calls on the enumeration will just throw exceptions.

    Now a situation like that does involve transactions and container automated things, but it's the programmer's fault for not coding against the tx attribute correctly. The container was just doing what it was told, only the instructions were bad. It is a good idea to test these things as they are critical parts of the application.
  16. Hi, This article talks mostly about testing the CRUD operations and transaction management that are performed by entity beans. But isn't that one of the main reason of using CMP?
    The entity beans used in the article are BMP entity beans. In that situation you really should be checking how the bean affects the database state.
    Because you trust the EJB container to do it right for you. It makes no sense to test the CMP implementation of a container, because most certainly it has been extensively tested before. When testing an entity bean, it would make more sense to test the domain specific methods (if there are any). By this I mean testing methods like computeLoanRate(), deposit() kind of methods.
    With CMP you don't necessarily need to check the database state, but should be testing all accessors, create methods, and finder methods. The CMP container only follows your instructions, you still are responsible for the O/R mapping, transaction attributes, and security attributes. That's a lot to screw up.

    The article has code that does just that. There are three different test cases for each entity:
      - Accessor Tests
      - Create Tests
      - Finder Tests
  17. Hi,
    The entity beans used in the article are BMP entity beans. In that situation you really should be checking how the bean affects the database state.
    I haven't noticed a BMP mention in the article, perhabs I must have my good morning cofee :-). However, if they are BMP entity beans that do basic CRUD operations any smoke test will show the bugs. Another way to test the one CRUD operations with another. For example if what you inserted is returned by the read operation then the test is ok. When doing this you have to becarefull to do the the CRUD operations in separate transactions.
    IMHO the CRUD unit testing on an entity bean (CMP or BMP) does not worth the effort, the bugs will be catched by a smoke test or a functional test.
    With CMP you don't necessarily need to check the database state, but should be testing all accessors, create methods, and finder methods. The CMP container only follows your instructions, you still are responsible for the O/R mapping, transaction attributes, and security attributes. That's a lot to screw up.
    That's more likely subject to a functional test, as someone has metioned before. This is because in most of the cases the transactions and security contexts get propagated to the entity beans from an upper level.


    Best regards, Mircea
  18. None of the above functionality can actually be tested in a faux-container environment. It just can't be done.
    Completely agree. But, why complicate things? What's wrong with remote testing/debugging? I can easily deploy ejb package into that server I use in production (remote, or on local machine - no matters) and run reflection-based client for _visual_ EJBs testing like great IBM UTC (by the way - like any other j2ee web application, it can easily be run inside any j2ee app server!). Then simply by 2-3 clicks on methods ensure that EJBs are alive an running right. And ... that's all!

    By the way - you can also debug EJBs in this manner - even just with simple and excellent IDEA tool! No need for any holty-tolty workshops. I've sucessfully used the same dev. environment and testing/debugging strategy for designing apps for WebLogic, WebSphere, JBoss and Orion.

    Best,
    --
    Mike
  19. None of the above functionality can actually be tested in a faux-container environment. It just can't be done.
    Completely agree. But, why complicate things? What's wrong with remote testing/debugging? I can easily deploy ejb package into that server I use in production (remote, or on local machine - no matters) and run reflection-based client for _visual_ EJBs testing like great IBM UTC (by the way - like any other j2ee web application, it can easily be run inside any j2ee app server!). Then simply by 2-3 clicks on methods ensure that EJBs are alive an running right. And ... that's all!By the way - you can also debug EJBs in this manner - even just with simple and excellent IDEA tool! No need for any holty-tolty workshops. I've sucessfully used the same dev. environment and testing/debugging strategy for designing apps for WebLogic, WebSphere, JBoss and Orion.Best,--Mike
    There's nothing wrong with that approach; if it works for you it works for you. Some people prefer a fully automated approach over one where starting/stopping and clicking is involved. The nice thing about using OpenEJB in your Cactus, Ant, Maven, or IDE ran test cases is that there is no interaction required to test -- OpenEJB will embed itself transparently the first time you try to access an EJB. You can easily have EJB test cases run as part of the automated build process just as easily and quickly as can with any other Junit test.

    Your way works, JunitEE works, Junit/OpenEJB works, Junit/Cactus with or without OpenEJB works, ... there are a few ways to test EJBs. The more the merrier. People who complain and slander EJB as not being testable are not paying attention.