Java unit test for different input data - java

I need to test some api. For example I have multiple #Test methods in the class to test my functionality, before init I connect to some url of my service, and use it.
If I have my service at multiple urls(different server environments), how can I Test this functionality for different service urls?
Flow:
Init conncetion by url
Run all Tests
Init conncetion by another url
Run all Tests(the same)
...
when was only one host I do like this:
public class TestAPI{
#org.junit.Before
public void init() {
service = new Service("www.test.com");
}
#org.junit.Test
public void testA(){
service.CallA();
}
#org.junit.Test
public void testB(){
service.CallB();
}
}

Happen to me sometime, and them I found this awesome idea called Parameterized Test, for instance:
http://www.mkyong.com/unittest/junit-4-tutorial-6-parameterized-test/
in this way you can all the same tests couple of time with different argument.

there are prameterized tests: http://www.mkyong.com/unittest/junit-4-tutorial-6-parameterized-test/ and http://ourcraft.wordpress.com/2008/08/27/writing-a-parameterized-junit-test/.
alternatively, you can make your test case abstract and subclass it with each subclass setting up the url.

Related

Java - Wiremock - Multiple Components

I've been trying to get this guide to work from Wiremock's documentation:
https://wiremock.org/docs/junit-jupiter/ - Advanced usage - programmatic
As I want to be able to mock multiple hosts simultaneously (same host, unique ports for my local environment). But I don't want these #RegisterExtension to be located in my test classes, instead in separate files but in doing so JUnit doesn't pick them up and I can't figure out why. Am I going about it in the wrong way?
Test code:
public class MyTest{
#Test
public void testMe(){
MyIntegration.mock();
}
}
public MyIntegration{
#RegisterExtension
static WireMockExtension wiremock = WireMockExtension.newInstance(wireMockConfig().port(9000)).build();
public static void mock(){
var info = wiremock.getRuntimeInfo(); // wireMockServer is null
wiremock.stubFor(...); // NPE
}
}
JUnit Jupiter scans test classes for #RegisterExtension annotations and runs the lifecycle methods on the annotated objects, but it won't scan non-test classes, which is why the server isn't being started in your example.
You have two options:
Create a base class with the WireMockExtension instances in it, then make each test class extend this.
In your integration class, new up an instance of WireMockServer, then make sure you call the start() and stop() methods on it before/after your test cases.
My preference is usually 1) in this scenario.

Close browser after several test classes

I work on an automated testing framework and I need to close the browser after passing tests on several test classes.
The package structure of the project is similar to this:
PackageA
SomeTestClass1
SomeTestClass2
...
PackageB
SomeOtherTestClass1
SomeOtherTestClass2
...
Note: There can be multiple levels of packages inside one another.
If I use #AfterClass or #AfterAll JUnit annotations I have to close the browser at the 'end' of each test class.
My framework requires launching the browser (as a static variable) and closing it only one time to speed up execution and avoid losing time for every browser launch and login, as I currently have a big number of tests that need to be run each night.
Is there any possiblity I could achieve this behaviour?
In JUnit 4, you could use the concept of Rule in conjunction with extending TestWatcher abstract class (org.junit.rules.TestWatcher).
Hence you won't have to close the browser in a method annotated with #AfterClass.
e.g.
public class StartFinishTestWatcher extends TestWatcher {
#Override
protected void starting(Description description) {
System.out.println("Starting test: " + description.getDisplayName());
}
#Override
protected void finished(Description description) {
System.out.println("Finishing test: " + description.getDisplayName());
// close the browser here
}
}
Then you would use this class in a RuleChain, in the test class(es) where you want to close the browser.
public class MyTestInWhichIWantBrowserToClose {
#Rule
public RuleChain ruleChain = buildTestRuleChain();
private RuleChain buildTestRuleChain() { // could be made protected and put in a superclass
return RuleChain.outerRule(new StartFinishTestWatcher());
}
}
In JUnit 5 you could create custom Test Suites and implement BeforeTestExecutionCallback and (in your case) AfterTestExecutionCallback interfaces in one of your base class.
You would then implement the custom logic which decides to close the browser in method public void afterTestExecution(ExtensionContext context).

Unit Test class that uses only local variables for composition

I am writing app that uses various REST api endpoints with very similar properties. Only difference is in endpoint adress and payload. Headers, method and other stuff remain the same. That is why I created class to communicate with my remote host, it is called RestApiCommunicator that has method generateRequestAndCallEndpoint(List payload) that wraps payload with all required stuff needed to perform rest call.
Than, I have various classes that only call this communicator class with proper endpoint suffix an its resources.
Everything is working fine but I want to unit test all of those classes. I was trying to figure out how to do that by reading a lot of SO questions but they are rather complicated cases, my is very simple.
I am trying to figure out a proper way to unit test a class that looks like this one:
class MyRestClient {
public void useRestApi(List<MyResources> myResources) {
RestApiCommunicator restApiCommunicator = new RestApiCommunicator ("/some/endpoint");
restApiCommunicator.generateRequestAndCallEndpoint(myResources);
}
}
I want to test if communicator was created with proper enpoint adress and if generateRequestAndCallEndpoint was called exacly once with my sample payload.
Only thing that comes to my mind is that make restApiCommunicator a field, create setter for this field and mock it in Unit tests. But this seems to me as rather dirty solution and I wouldn't like to modify my code to allow tests.
Maybe you can point me in some direction where I could have this class tested using some good pattern.
(ps. If that matters - this is a Spring Boot app)
You could provide a factory for the communicator
class MyRestClient {
private RestApiCommunicatorFactory factory = ...
public void useRestApi(List<MyResources> myResources) {
factory.getCommunicator("/some/endpoint")
.generateRequestAndCallEndpoint(myResources);
}
In your unit test, you provide a mock of the factory, which returns mock communicators. The specific language for that depends on your mocking library of choice.
One way to do exactly what you ask (ie, "to test if communicator was created with proper enpoint adress and if generateRequestAndCallEndpoint was called exactly once with my sample payload") is to mock it using JMockit:
public final class MyRestClientTest {
#Tested MyRestClient restClient;
#Mocked RestApiCommunicator restApi;
#Test
public void verifyUseOfRestApi() {
List<MyResource> resources = asList(new MyResource("a"), new MyResource("b"));
restClient.useRestApi(resources);
new Verifications() {{
new RestApiCommunicator("/some/endpoint");
restApi.generateRequestAndCallEndpoint(resources); times = 1;
}};
}
}

Structing my Selenium Test

I have a Selenium test case that I need to write, but before it executes I need to get some information from the user for the Test to run.
Currently, my code is structured like this:
public class myTest {
private WebDriver driver;
#Before
System.setProperty("webdriver.ie.driver",
"C:\\Users\\ktuck\\Documents\\Selenium\\Selenium Server\\IEDriverServer.exe");
driver = new InternetExplorerDriver(); // I guess I don't need to fire this up as i'm only collecting information from the user?
#Test
// Code to collect user inputted data to use later in my test
#After
public void tearDown() throws Exception {
driver.quit(); // Do I need this?
}
}
My initial thoughts were to put the collection code inside of a main function and then call the rest of my test script which would be in a different file, passing the information collected into it. But I'm not quite sure how to do that as I'm quite new to Selenium/Java :p
Can anyone help?
If you are not using any testing framework , you can choose TestNG. TestNG supports Data driven and parameterized test.
you can pass param via testng.xml.
since you are using maven you can configure maven to pass parameters without using testng.xml.
you can also pass params to TestNG via maven through command line like below
mvn -Dtest=<testName> -D<paramName>=<paramValue> test
if you dont want to use any of the testing framework then you can pass the param via JVM arg
and retrive it using System.getProperty("paramName")
Consider using a test framework like JUnit or TestNG. This would enable you to use methods that are run before and after the actual test (as indicated by the pseudo-code given above).
Using this approach, you can do all the lookup stuff in the #BeforeClass method and quit the webdriver in the #AfterTest method. To keep the test class clean, I recommend to move the #BeforeClass and #AfterTest to an abstract super class which you inherit from.
Abstract Superclass
public abstract class AbstractSeleniumTest {
private WebDriver webDriver;
#BeforeClass
public void setup() {
// do all the initalization stuff, e.g. system property lookup
}
#AfterTest(alwaysRun = true)
public void tearDown() {
// do all the clean-up stuff, e.g. webdriver.quit();
}
}
Test Class
#Test
public class MySeleniumTest extends AbstractSeleniumTest {
public void testSomething() {
// do the actual test logic
}
}
I hope this covers most of your question. For further assistance, please give more information.

Selenium, minimizing repetitious code

The selenium tests I'm gonna be doing are basically based on three main steps, with different parameters. These parameters are passed in from a text file to the test. this allows easy completion of a test such as create three of "X" without writing the code to do the create three times in one test.
Imagine i have a test involving creating two of "X" and one of "Y". CreateX and CreateY are already defined in separate tests. Is there a nice way of calling the code contained in createX and createY from say, Test1?
I tried creating a class with the creates as seperate methods, but got errors on all the selenium.-anything-, ie every damn line. it goes away if i extend seleneseTestCase, but it seems that my other test classes wont import from a class that extends seleneseTestCase. I'm probably doing something idiotic but i might as well ask!
EDIT:
well for example, its gonna be the same setUp method for every test, so id like to only write that once... instead of a few hundred times...
public void ready() throws Exception
{
selenium = new DefaultSelenium("localhost", 4444, "*chrome", "https://localhost:9443/");
selenium.start();
selenium.setSpeed("1000");
selenium.setTimeout("999999");
selenium.windowMaximize();
}
thats gonna be used EVERYWHERE.
its in a class called reuseable. Id like to just call reuseable.ready(); from the tests SetUp... but it wont let me....
public class ExampleTest {
#Before
public void setup() {
System.out.println("setup");
}
public void someSharedFunction() {
System.out.println("shared function");
}
#Test
public void test1() {
System.out.println("test1");
someSharedFunction();
}
#Test
public void test2() {
System.out.println("test2");
someSharedFunction();
}
}
The contents of the function after the #Before annotation is what will be executed before every test. someSharedFunction() is an example of a 'reusable' function. The code above will output the following:
setup
test1
shared function
setup
test2
shared function
I would recommend using JUnit and trying out some of the tutorials on junit.org. The problem you have described can be fixed using the #Before annotation on a method that performs this setup in a super class of your tests

Categories

Resources