I am wondering if there is a way to access the code of the Java WS application.
I would like to find an alternative method of application automation (directly calling procedures and passing parameters) instead of using some external UI automation software.
Does anybody have any thought? or this is a bad idea to go this way?
Well, Server-Side code, e.g. WebService/Servlets, etc, are meant to be deployed to a web container, and accessed and tested by external applications.
However, usually you can write JUnit tests mocking the application server objects, e.g. HttpServletRequest, HttpSession by libraries like mockito or EasyMock. Mocking can go all the way to simulate values from database, server-parameters, potentially all dependencies of your test code.
Sometimes, you can also write JUnit tests with Java Reflection, to ensure correct values of Annotations, to test something like:
#WebService(name = "myWebService", serviceName = "SomekWebService",
portName = "AnotherWebServicePort", targetNamespace = "http://www.mine.com/ws/hello")
Usually, a project has both simple JUnit tests if possible, but also full integration tests with running on the server, in cases you need to get actual values.
Related
I recently started looking into BDD(using Gherkin + Restassured). Need to mock third party servicd, below is my use case.
Service-A internally calls Service-B
The application is in goLang.
The BDD are in Java.
We have a CI pipeline running along, where it generates the rpm and deploys the rpm into VM.
On that VM we are running the BDD(Currently Service-A and Service-B are deployed on the same VM)
Is ther a way i can mock the Service-B, so that i dont have to be dependent on Service-B? If yes what would be the best approach here.
Have tried goLang httptest to mock the service at the unit-test level.
But how the mocking can be done after rpm gets created in pipeline with BDD in place.
Thanks
If your Service A is calling Service B internally, rather than via web or RPC, then you can use dependency injection to inject a "fake" version of your Service B. (Note that this doesn't necessarily involve a dependency injection framework; constructor-based and property-based injection are also valid). If Service B has no interface, extract one and use a thin adapter to call the real service or fake depending on environment.
You won't need to change your scenarios as long as they are only interacting with Service A's user interface or API.
You will need to change the way the build pipeline works, so that it deploys with your fake instead of the real code.
You can even do this at runtime, switching over from the fake to the real thing by having the adapter call the relevant service. The switch or deployment can be triggered by environment variables or by build arguments.
Be careful not to deploy your test service to production though!
If you're using continuous deployment, then the last step in the build pipeline should ideally deploy and test interaction with the real service. If for some reason that's the only way you can work, there are still a couple of things you can do that might help:
You can stub the data that Service B uses, so that it behaves in a predictable way
You can use a test instance. Reach out to your service provider and see if they have one for you. I recommend that you should still check that deployment of the real service succeeds, ideally with an automated test of some sort, even if that has to be run in production. It only needs to be a basic smoke test to check that the system is wired up. Note that the easier it is to deploy, the easier it will be to recover from any mistakes; if you can't deploy quickly then you will need to be more thorough in your checking.
If the RPM is created and deployed without any kind of fake or test instance, and you have no way to configure the environment to use such a fake or test instance, then you will not be able to mock it out. The build pipeline has to be a part of deploying a fake. That won't be a problem if you have control over your CI pipeline; otherwise reach out to your build team. They may have experience or be able to point you to someone else who can help you. Great BDD is driven by conversations, after all!
We are currently improving the test coverage of a set of database-backed applications (or 'services') we are running by introducing functional tests. For me, functional tests treat the system under test (SUT) as a black box and test it through its public interface (be it a Web interface, REST, or our potential adventure into the messaging realm using AMQP).
For that, the test cases either A) bootstrap an instance of the application or B) use an instance that is already running.
The A version allows for test cases to easily test the current version of the system through the test phase of a build tool or inside a CI job. That is what e.g. the Grails functional test phase is for. Or Maven could be set up to do this.
The B version requires the system to already run but the system could be inside (or at least closer to) a production environment. Grails can do this through the -baseUrl option when executing functional tests.
What now puzzles me is how to achieve a required state of the service prior to the execution of every test case?
If I e.g. want to test a REST interface that does basic CRUD, how do I create an entity in the database so that I can test the HTTP GET for it?
I see different possibilities:
Using the same API (e.g. HTTP POST) to create the entity. Downside: Changing the creation method breaks two test cases. Furthermore, there might not be a creation method for all APIs.
Adding an additional CRUD API for testing and only activating that in non-production environments. That API is then used for testing. Downside: adds additional code to the production system, API logic might not be trivial, e.g. creation of complex entity graphs (through aggregation/composition), and we need to make sure the API is not activated for production.
Basically the same approach is followed by the Grails Remote Control plugin. It allows you to "grab into your application" and invoke arbitrary code through serialisation. Downside: Feels "brittle". There might be similar mechanisms for different languages/frameworks (this question is not Grails specific).
Directly accessing the relational database and creating/deleting content, e.g. using DbUnit or just manually creating entities through JDBC. Downside: you duplicate creation/deletion logic and/or ORM inside the test case. Refactoring the DB breaks the test case though the SUT still works.
Besides these possibilities, Grails when using the (-inline) option for functional tests allows accessing Spring services (since the application instance is run inside the same JVM as the test case). Same applies for Spring Boot "integration tests". But I cannot run the tests against an already running application version (as described as option B above).
So how do you do that? Did I miss any option for that?
Also, how do you guarantee that each test case cleans up after itself properly so that the next test case sees the SUT in the same state?
as with unit testing you want to have a "clean" database before you run a functional test. You will need some setup/teardown functionality to bring the database into a defined state.
easiest/fastest solution to clean the database is to delete all content with an sql script. (For debugging it is also useful to run this in the test setup to keep the state of the database after a test failure.) This can be maintained manually (it just contains delete <table> statements). If your database changes often you could try to generate the clean script (disable foreign keys (to avoid ordering problem), delete tables).
to generate test data you can use an sql script too but that will be hard to maintain, or create it by code. The code can be placed in ordinary Services. If you don't need real production data the build-test-data plugin is a great help at simplifying test data creation. If you are on the code side it also makes sense to re-use the production code to create test data to avoid duplication.
to call the test data setup simply use remote-control. I don't think it is more brittle than all the http & ajax stuff ;-). Since we now have all the creation code in a service the only thing you need to call with remote control is the Service that does create the data. It does not have to get more complicated than remote { ctx.testDataService.setupDataForXyz() }. If it is that simple you can even drop remote-control and use a controller/action to run it.
do not test too much detail with functional tests to make it not more complicated as it already is. :)
I am writing some test cases for action and tag classes. I figure out that spring provides mocks for all web interfaces e.g request/response/session etc under org.springframework.mock.web package.
Any idea whats the difference in using these mocks v/s inject mocks using #mock annotation?
The mock classes in Spring have actual functionality. They can, for example, respond to JSP include or redirect requests or they can return you the output of the web code as a string (i.e. what the browser would get).
When using mocks, you have to implement every method call that would be made yourself. This works well for simple cases but web objects like response have a state (for example, the response which the code generates). These often do not like mocking. Or rather you can mock them but at the cost of your test not having access to the code's output.
How do you guys Test your SOAP Services? Do you use Tools like soapUI or do you write Unit Tests?
Just wanted to hear some opinions, what you prefer, what the advantages or disadvantages of both approaches are? And if someone writes Unit Tests, can you give me an example how to write those???
Edit: I developed a lot of REST services, which I usually tested using JUnit and a REST Client Framework. So when the REST Service was deployed, I was able to invoke those services with as a JUnit Test using a http connection. Is there something similiar in SOAP too? Does anyone have an example code for a SOAP Client?
The best way to test your SOAP service is by using the SOAPUI testing tool.
With JDEF you can create your SOAP Application, following SOAP standards - and then easily verify this through the Enterprise Manager Console provided by Oracle.
You just get an instance of that particular service, and then you can see the audit flow.
I use both Junit for functional low-level testing of my functions and back end code. And I use SOAPUI to test the Web Service. Also keep in mind that you can run SOAPUI tests from within unit tests as desribed here. example:
public void testRunner() throws Exception
{
SoapUITestCaseRunner runner = new SoapUITestCaseRunner();
runner.setProjectFile( "src/dist/sample-soapui-project.xml" );
runner.run();
}
If you like to test services you can use SOAPUI tool which is easy. But if you like to test service's functions are wroking right or not, you need to right unitest. That means if you are the author of the webservice, you might need to write unittests to check the functionalities.
I'm using both. Basically JUnit for simple automated unit tests. And SoapUI for more complex system tests which make more that a single web service call.
I've written a small library which does most of the heavy lifting of unit-testing SOAP services. Basically you'll get mockito mocks which are easy to work with.
I have a web service which calls a third party web service.
Now I want to unit-test my web service. For this, should I mock the third party web service or is it fine to call it during the tests?
Is there any standard document on unit testing?
Yes, you should mock the third party web service for unit testing. Here are some advantages:
Your unit tests are independent of other components and really only test the unit and not also the web service. If you include the service in your unit tests and they fail, you won't know whether the problem is in your code or in the foreign web service.
Your tests are independent of the environment. If the Internet connection is ever down or you want to test on a machine that doesn't have Internet access at all, your test will still work.
Your tests will be much faster without actually connecting to the web service. This might not seem like a big thing but if you have many many tests (which you should), it can really get annoying.
You can also test the robustness of your unit by having the mock send unexpected things. This can always happen in the real world and if it does, your web service should react nicely and not just crash. There is no way to test that when using the real web service.
However, there is also integration testing. There, you test the complete setup, with all components put together (integrated). This is where you would use the real web service instead of the mock.
Both kinds of testing are important, but unit testing is typically done earlier and more frequently. It can (and should) be done before all components of the system are created. Integration testing requires a minimal amount of progress in all of most of the components.
This depend on what you're unit-testing.
So if you're testing out whether you can successfully communicate with the third-party webservice, you wouldn't obviously try to mock this. However if you're unit-testing some business use-cases that are part of your web-service offering (unrelated to what the other modules/web services are doing), then you might want to mock the third-party web service.
You should test both but both test cases does not fall under Unit testing.
Unit testing is primarily used for testing individual smaller pieces i.e. classes and methods. Unit testing is something that should preferably happen during the build process without any human intervention. So as part of Unit testing you should mock out the third party webservice. The advantage of mocking is that you can make the mocked object behave in many possible ways and test your classes/methods to make sure they handle all possible cases.
When multiple systems are involved, the test case falls under System/Integration/Functional testing. So as part of your System/Integration/Functional testing, you should call the methods in other webservice from your webservice and make sure everything works as expected.
Mocking is an usually essential in unit testing components which have dependent components. This is so because in unit testing , you are limited to testing that your code works correctly ( does what its contract says it will do ). If this method , in trying to do the part of its contract depends upon other component doing their part correctly , it is perfectly fine to mock that part out ( assuming that they work correctly ).
If you dont mock the other dependent parts , you soon run into problems. First , you cannot be certain what behavior is exhibited by that component. Second , you cannot predict the results of your own test ( because you dont know what was the inputs supplied to your tests )