3

I am currently attempting to integrate automated tests with our test management tool with the use of APIs. Each test(which is contained in a single class) has a unique id which needs to be referenced in the API call. I can either declare the Test IDs in the tests themselves (preferred) or create a separate class that contains all of the IDs for reference. The issue I am having is coming up with a good way to represent these IDs as a variable when the particular test is run, so I do not a have to repeat the API framework for each unique ID.

Here is the general set up of the API class/listener class.

  package testPackage;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;

import org.json.simple.JSONObject;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;

import com.gurock.testrail.APIClient;
import com.gurock.testrail.APIException;


public class MyTestResultsListener extends TestListenerAdapter {

    public final APIClient client = new APIClient("https://api.url/");
    public final Map data = new HashMap();

    public final void APISendCredentials() {
        client.setUser("username");
        client.setPassword("password");


    }

    @Override
    public void onTestFailure(ITestResult result) {
        APISendCredentials();
        data.put("status_id", new Integer(5));
        data.put("comment", "This test failed");
        try {
            JSONObject r = (JSONObject) client.sendPost("add_result_for_case/" + "Unique ID", data);
        } catch (MalformedURLException e) {

            e.printStackTrace();
        } catch (IOException e) {

            e.printStackTrace();
        } catch (APIException e) {

            e.printStackTrace();
        }
    }

    @Override
    public void onTestSuccess(ITestResult result) {
        APISendCredentials();
        data.put("status_id", new Integer(1));
        data.put("comment", "This test passed");
        try {
            JSONObject r = (JSONObject) client.sendPost("add_result_for_case/" + TestClass.AutomationID, data);
        } catch (MalformedURLException e) {

            e.printStackTrace();
        } catch (IOException e) {

            e.printStackTrace();
        } catch (APIException e) {

            e.printStackTrace();
        }

    }

    @Override
    public void onTestSkipped(ITestResult result) {
        APISendCredentials();
        data.put("status_id", new Integer(2));
        data.put("comment", "This test was blocked or skipped");
        try {
            JSONObject r = (JSONObject) client.sendPost("add_result_for_case/" + TestClass.AutomationID, data);
        } catch (MalformedURLException e) {

            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (APIException e) {
            e.printStackTrace();
        }

    }
}

Test class

package testPackage;

import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import com.gurock.testrail.APIException;

@Listeners(MyTestResultsListener.class)

public class TestClass {

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TestData {
    String testId() default "0";

}

public static String AutomationID = "236/50819";

@Test
@TestData(testId = "236/50819")
public void test1() {
    //sometest 

}

@AfterTest
public void aftertest() {
    //This was my initial blind attempt at reflection. I am getting 
    //an error below stating "test1" cannot be resolved to a variable 
    //also unclear on how to feed this to the APIclass 
    Method testMethod = getClass().getMethod(test1);
    if (testMethod.isAnnotationPresent(TestData.class)) {
        TestData testData = testMethod.getAnnotation(TestData.class);
        //stuck at this point 
    }
}

}

As you can see on the lines that start with JSONobject r I have a place holder for the uniqueID variable. What would be the best way/most efficient way to create a variable that could take these unqiue IDs from the different test classes ?

Thx, let me know if there is any additional information needed that would be helpful !

Lamar
  • 63
  • 8
  • I'm not sure what you mean by "repeat the API framework", but the usual answer to this sort of thing is to create an interface such as `HasTestId`. – chrylis -cautiouslyoptimistic- Jul 06 '17 at 19:02
  • Where's the `onTestFailure` method? I mean, in which class is it declared? Do you have a superclass for all your tests? Please show the skeleton of your tests. – fps Jul 06 '17 at 20:10

1 Answers1

2

If the id for each test does not change, you can create an annotation e.g. @TestId holding the test id. Each test class (or method depending on the granularity level desired) can be annotated with its own test id. Then in the API code you can simply get it via reflection.

jingx
  • 3,698
  • 3
  • 24
  • 40
  • So using this method I would replace "uniqueid" in the api call with TestId ? – Lamar Jul 06 '17 at 19:24
  • Well, annotate your test class with something like `@TestId("test123")`. Then when you need the test id for the URL, you can get to the current test class via `ITestResult`, and use reflection to get the `@TestId` value on that test class. – jingx Jul 06 '17 at 20:00
  • Can you post a simple example ? I am unfamiliar with reflection and can't find a good example for this case. – Lamar Jul 06 '17 at 20:59
  • There are plenty examples if you just google "java get annotation value". For example https://stackoverflow.com/questions/20192552/get-value-of-a-parameter-of-an-annotation-in-java – jingx Jul 07 '17 at 15:50