Difficulties leveraging Testng, due to test design

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Difficulties leveraging Testng, due to test design

Joe DeSantis
All of my test cases extend off of a abstract class that has a bunch of methods: setup, run, teardown etc (this was built prior to testng implementation).
The issue is all of my tests require a new instance of the test class, which would work great with junit, but has caused me alot of pain with testng.

I have annotiated my base class run method with @Test. So if my class has a no args constructor, and only runs once everything works beautiful.
For example, for my no args test, i can just reference my class in the testing xml config and it will run no problems.
The issue is when my tests are dynamically ran, which from inception of the our testing framework was done by constructor args.

For example I have a test called test1, where the constructor take an enum that drives the tests experience.
Each test needs its own attributes (webdriver/selenium/etc) which are provided fresh with every instance of my abstract class.
So I need another instance of the test class.

Now I have gotten a factory to execute my tests successfully any everything works great except one thing.
I can't select specific tests cases. IE. the factory is loaded up with 10 instances of my test, without a code change I can't select one test case.
I could create another class per test case, but that causes a bunch of class bloat.

More concise but still dirty in my own opinion I could extend my test clases and provide the constructor arg for each of test cases for the super, and then have a no args
constructor for my child class that testng would have no issue running. 
This causes a ton of class bloat.
public class test1BestCompany extends test1{
 
public test1BestCompany() {
 
super(Affiliates.BESTCOMPANY);
 
}
}



@Test
public void runTestBestCompany(){
   
new test1(Affiliates.BESTCOMPANY).run();
}
@Test
public void runTestWrongCompany(){
   
new test1(Affiliates.WRONGCOMPANY).run();
}


There has to be something better than the crazy solutions I have came up with.
Thanks,
Joe

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Difficulties leveraging Testng, due to test design

Joe DeSantis
I have posted on stackoverflow a better representation of my class structure/problem:
https://stackoverflow.com/questions/50089347/difficulties-leveraging-testng-with-preexisting-test-architecture



On Friday, April 27, 2018 at 7:54:17 PM UTC-4, Joe DeSantis wrote:
All of my test cases extend off of a abstract class that has a bunch of methods: setup, run, teardown etc (this was built prior to testng implementation).
The issue is all of my tests require a new instance of the test class, which would work great with junit, but has caused me alot of pain with testng.

I have annotiated my base class run method with @Test. So if my class has a no args constructor, and only runs once everything works beautiful.
For example, for my no args test, i can just reference my class in the testing xml config and it will run no problems.
The issue is when my tests are dynamically ran, which from inception of the our testing framework was done by constructor args.

For example I have a test called test1, where the constructor take an enum that drives the tests experience.
Each test needs its own attributes (webdriver/selenium/etc) which are provided fresh with every instance of my abstract class.
So I need another instance of the test class.

Now I have gotten a factory to execute my tests successfully any everything works great except one thing.
I can't select specific tests cases. IE. the factory is loaded up with 10 instances of my test, without a code change I can't select one test case.
I could create another class per test case, but that causes a bunch of class bloat.

More concise but still dirty in my own opinion I could extend my test clases and provide the constructor arg for each of test cases for the super, and then have a no args
constructor for my child class that testng would have no issue running. 
This causes a ton of class bloat.
public class test1BestCompany extends test1{
 
public test1BestCompany() {
 
super(Affiliates.BESTCOMPANY);
 
}
}



@Test
public void runTestBestCompany(){
   
new test1(Affiliates.BESTCOMPANY).run();
}
@Test
public void runTestWrongCompany(){
   
new test1(Affiliates.WRONGCOMPANY).run();
}


There has to be something better than the crazy solutions I have came up with.
Thanks,
Joe

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Difficulties leveraging Testng, due to test design

⇜Krishnan Mahadevan⇝

Joe,

 

I think this can be solved. But I need to get some specifics from you.

 

You mention that your test class has a non-default constructor which gets injected with values for it to be able to be instantiated and perhaps consumed later by the test methods in it.

But how do you envision the values to be injected into the constructor?

 

For e.g.,

 

public class sampletest2 extends AbstractValidator2{

    Date date;

    public sampletest2(String url, Date date) {

        super(url, null);

        date = date;

    }

    @Override

    public boolean validate() {

        driver.get(url);

        Utils.wait(5000);

        return false;

    }

}

 

In the above sample, how does one get the values for url and date ? where would they come from ?

 

I read through your comments and understand that with Factory+DataProvider approach (which is the logical solution that would best fit your situation), you say that you cant run cases on a one-off basis. But if you are willing to fiddle your data source (perhaps if its part of a DB or an excel spreadsheet), you can add a flag which tells the data provider implementation that a specific row has to be included/excluded. Would that not work for you ?

 

W.r.t the webdriver instantiation etc., there are ways of doing it. You could for e.g., leverage a ThreadLocal and abstract out the webdriver instantiation out from your test class (See this blog of mine for an example)

 

If you are bent on using a @BeforeMethod/@AfterMethod approach, then you could have your webdriver instantiated via it, and injected into a test method’s ITestResult object, which would later be consumed by the test method. See below example

 

import org.testng.Assert;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class NativeInjection {
 
private static final String KEY = "key";
 
private static final String VALUE = "Krishnan";

 
@BeforeMethod
 
public void beforeMethod(ITestResult result) {
   
// Adding an assert to showcase that its indeed the "to be run @Test method's ITestResult
    // object" that is getting injected here.
   
Assert.assertEquals(result.getMethod().getMethodName(), "testMethod");
    result.setAttribute(
KEY, VALUE);
  }

 
@Test
 
public void testMethod() {
    String actualValue = getCurrentValue()
    Assert.assertEquals(actualValue,
VALUE);
  }

 
private String getCurrentValue() {
   
return Reporter.getCurrentTestResult().getAttribute(KEY).toString();
  }
}

 

 

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

From: <[hidden email]> on behalf of Joe DeSantis <[hidden email]>
Reply-To: <[hidden email]>
Date: Sunday, April 29, 2018 at 10:55 PM
To: testng-users <[hidden email]>
Subject: [testng-users] Re: Difficulties leveraging Testng, due to test design

 

I have posted on stackoverflow a better representation of my class structure/problem:

https://stackoverflow.com/questions/50089347/difficulties-leveraging-testng-with-preexisting-test-architecture

 



On Friday, April 27, 2018 at 7:54:17 PM UTC-4, Joe DeSantis wrote:

All of my test cases extend off of a abstract class that has a bunch of methods: setup, run, teardown etc (this was built prior to testng implementation).

The issue is all of my tests require a new instance of the test class, which would work great with junit, but has caused me alot of pain with testng.

 

I have annotiated my base class run method with @Test. So if my class has a no args constructor, and only runs once everything works beautiful.

For example, for my no args test, i can just reference my class in the testing xml config and it will run no problems.

The issue is when my tests are dynamically ran, which from inception of the our testing framework was done by constructor args.

 

For example I have a test called test1, where the constructor take an enum that drives the tests experience.

Each test needs its own attributes (webdriver/selenium/etc) which are provided fresh with every instance of my abstract class.

So I need another instance of the test class.

 

Now I have gotten a factory to execute my tests successfully any everything works great except one thing.

I can't select specific tests cases. IE. the factory is loaded up with 10 instances of my test, without a code change I can't select one test case.

I could create another class per test case, but that causes a bunch of class bloat.

 

More concise but still dirty in my own opinion I could extend my test clases and provide the constructor arg for each of test cases for the super, and then have a no args

constructor for my child class that testng would have no issue running. 

This causes a ton of class bloat.

public class test1BestCompany extends test1{
 
public test1BestCompany() {
 
super(Affiliates.BESTCOMPANY);
 
}
}
 

 

 

@Test
public void runTestBestCompany(){
   
new test1(Affiliates.BESTCOMPANY).run();
}
@Test
public void runTestWrongCompany(){
   
new test1(Affiliates.WRONGCOMPANY).run();
}

 

There has to be something better than the crazy solutions I have came up with.

Thanks,

Joe

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
[hidden email].
To post to this group, send email to
[hidden email].
Visit this group at
https://groups.google.com/group/testng-users.
For more options, visit
https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Difficulties leveraging Testng, due to test design

Joe DeSantis
In reply to this post by Joe DeSantis
I have now uploaded a repo to github, so everyone can run, review runnable code.
In it I have 3 workarounds that I have used, and in the comments I list some of pro/cons of the workarounds/hacks.

https://github.com/Warfront1/TestNG-Create-Individual-Instances

On Friday, April 27, 2018 at 7:54:17 PM UTC-4, Joe DeSantis wrote:
All of my test cases extend off of a abstract class that has a bunch of methods: setup, run, teardown etc (this was built prior to testng implementation).
The issue is all of my tests require a new instance of the test class, which would work great with junit, but has caused me alot of pain with testng.

I have annotiated my base class run method with @Test. So if my class has a no args constructor, and only runs once everything works beautiful.
For example, for my no args test, i can just reference my class in the testing xml config and it will run no problems.
The issue is when my tests are dynamically ran, which from inception of the our testing framework was done by constructor args.

For example I have a test called test1, where the constructor take an enum that drives the tests experience.
Each test needs its own attributes (webdriver/selenium/etc) which are provided fresh with every instance of my abstract class.
So I need another instance of the test class.

Now I have gotten a factory to execute my tests successfully any everything works great except one thing.
I can't select specific tests cases. IE. the factory is loaded up with 10 instances of my test, without a code change I can't select one test case.
I could create another class per test case, but that causes a bunch of class bloat.

More concise but still dirty in my own opinion I could extend my test clases and provide the constructor arg for each of test cases for the super, and then have a no args
constructor for my child class that testng would have no issue running. 
This causes a ton of class bloat.
public class test1BestCompany extends test1{
 
public test1BestCompany() {
 
super(Affiliates.BESTCOMPANY);
 
}
}



@Test
public void runTestBestCompany(){
   
new test1(Affiliates.BESTCOMPANY).run();
}
@Test
public void runTestWrongCompany(){
   
new test1(Affiliates.WRONGCOMPANY).run();
}


There has to be something better than the crazy solutions I have came up with.
Thanks,
Joe

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Difficulties leveraging Testng, due to test design

⇜Krishnan Mahadevan⇝

Joe,

 

Please check if the below is a viable solution for you (based on the sample project you shared). This would mean that you would essentially create variants and perhaps add more conditions to the base class as annotations etc.,  But I think this sample should elaborate what I am trying to convey.  Let me know how it goes.

 

A sample annotation that is used to represent the parameters that should be injected into a @Test method.

 

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;

@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({METHOD, TYPE})
public @interface InjectParameters {
  String url()
default "";

  String getComplexClass()
default "testngImplementation.acomplexclass";
}

 

The revamped base class would look like below:

 

import org.testng.IHookCallBack;
import org.testng.IHookable;
import org.testng.ITestResult;
import org.testng.internal.ClassHelper;

import java.util.ArrayList;
import java.util.List;

public class AbstractValidator implements IHookable {

 
public AbstractValidator() {
   
// more common setups reports, selenium, utilities, etc...
 
}

 
public void setup() {}

 
public void tearDown() {}

 
@Override
 
public void run(IHookCallBack callBack, ITestResult testResult) {
    System.
out.println("We made it to run on the Abstract Validator 2");
    setup();
    Object[] parameters = callBack.getParameters();
    Object[] injected = getParametersToInject(testResult);
   
if (parameters.length == injected.length) {
      System.arraycopy(injected,
0, parameters, 0, parameters.length);
    }
    callBack.runTestMethod(testResult);
    tearDown();
  }

 
private Object[] getParametersToInject(ITestResult testResult) {
    List<Object> parameters =
new ArrayList<>();
   
InjectParameters toInject =
        testResult
            .getMethod()
            .getConstructorOrMethod()
            .getMethod()
            .getAnnotation(
InjectParameters.class);
   
if (toInject != null) {
      parameters.add(toInject.url());
      parameters.add(ClassHelper.newInstance(ClassHelper.forName(toInject.getComplexClass())));
    }
   
return parameters.toArray(new Object[0]);
 }
}

 

 

The actual test class would look like below:

 

import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import testngImplementation.acomplexclass;

public class TestCreation extends AbstractValidator {
 
@Test
  @InjectParameters
(url = "https://www.google.com/")
 
// The @Parameters is being used just as a place holder here. To prevent TestNG from triggering
  // Validations saying that parameter required but not provided. I think this would be fixed
  // as part of fix for https://github.com/cbeust/testng/issues/564 which would be available in
  // TestNG 7.0.0

 
@Parameters({"url", "a"})
 
public void sampletest2google(@Optional String url, @Optional acomplexclass a) {
    System.
err.println("URL is " + url);
    System.
err.println("Complex object  is " + a.toString());
  }

 
@Test
  @InjectParameters
(url = "https://www.bing.com/")
 
@Parameters({"url", "a"})
 
public void sampletest3bing(@Optional String url, @Optional acomplexclass a) {
    System.
err.println("URL is " + url);
    System.
err.println("Complex object  is " + a.toString());
  }
}

 

And here’s the execution output:

 

We made it to run on the Abstract Validator 2

URL is https://www.google.com/

Complex object  is testngImplementation.acomplexclass@737996a0

We made it to run on the Abstract Validator 2

URL is https://www.bing.com/

Complex object  is testngImplementation.acomplexclass@12843fce

 

===============================================

Default Suite

Total tests run: 2, Failures: 0, Skips: 0

===============================================

 

 

 

 

 

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

From: <[hidden email]> on behalf of Joe DeSantis <[hidden email]>
Reply-To: <[hidden email]>
Date: Wednesday, May 2, 2018 at 11:05 AM
To: testng-users <[hidden email]>
Subject: [testng-users] Re: Difficulties leveraging Testng, due to test design

 

I have now uploaded a repo to github, so everyone can run, review runnable code.

In it I have 3 workarounds that I have used, and in the comments I list some of pro/cons of the workarounds/hacks.

 

https://github.com/Warfront1/TestNG-Create-Individual-Instances

On Friday, April 27, 2018 at 7:54:17 PM UTC-4, Joe DeSantis wrote:

All of my test cases extend off of a abstract class that has a bunch of methods: setup, run, teardown etc (this was built prior to testng implementation).

The issue is all of my tests require a new instance of the test class, which would work great with junit, but has caused me alot of pain with testng.

 

I have annotiated my base class run method with @Test. So if my class has a no args constructor, and only runs once everything works beautiful.

For example, for my no args test, i can just reference my class in the testing xml config and it will run no problems.

The issue is when my tests are dynamically ran, which from inception of the our testing framework was done by constructor args.

 

For example I have a test called test1, where the constructor take an enum that drives the tests experience.

Each test needs its own attributes (webdriver/selenium/etc) which are provided fresh with every instance of my abstract class.

So I need another instance of the test class.

 

Now I have gotten a factory to execute my tests successfully any everything works great except one thing.

I can't select specific tests cases. IE. the factory is loaded up with 10 instances of my test, without a code change I can't select one test case.

I could create another class per test case, but that causes a bunch of class bloat.

 

More concise but still dirty in my own opinion I could extend my test clases and provide the constructor arg for each of test cases for the super, and then have a no args

constructor for my child class that testng would have no issue running. 

This causes a ton of class bloat.

public class test1BestCompany extends test1{
 
public test1BestCompany() {
 
super(Affiliates.BESTCOMPANY);
 
}
}
 

 

 

@Test
public void runTestBestCompany(){
   
new test1(Affiliates.BESTCOMPANY).run();
}
@Test
public void runTestWrongCompany(){
   
new test1(Affiliates.WRONGCOMPANY).run();
}

 

There has to be something better than the crazy solutions I have came up with.

Thanks,

Joe

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
[hidden email].
To post to this group, send email to
[hidden email].
Visit this group at
https://groups.google.com/group/testng-users.
For more options, visit
https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Difficulties leveraging Testng, due to test design

Joe DeSantis
In reply to this post by Joe DeSantis
Krishnan Mahadevan,

Thanks for the continued help.
I was able to get your example running, and pushed it up to my test repo.
There did seem to be issues with the approach though:
- I couldn't figure out a way to use a pre-instantiated instance of "acomplexclass" via the @InjectParameters
- Also, I know it wasn't clear in my minimal example, but different tests (that all extent my AbstractValidator2) have different constructors.

For example one of my most extreme tests classes has a constructor like the following:
String url, WebDriver driver, String partnerToRequest, IPRequester requester, boolean featuretoggleflag
Others take a varying range of different arguments (numerous to none): enums, booleans, custom class instances, etc.

Every time I want to create a new test with that requires a new class in its constructor I will have to duplicate code in the @InjectedParameters and/or getParametersToInject on Abstract Validator.

On the side, I attempted to see if I could get the functionality I was looking for using Junit 5.
The running of individual tests did seem easy to configure, I am now trying to figure out how to create suites(not as much of a first class consideration as testng) and run in parallel.




Each Test class,

On Friday, April 27, 2018 at 7:54:17 PM UTC-4, Joe DeSantis wrote:
All of my test cases extend off of a abstract class that has a bunch of methods: setup, run, teardown etc (this was built prior to testng implementation).
The issue is all of my tests require a new instance of the test class, which would work great with junit, but has caused me alot of pain with testng.

I have annotiated my base class run method with @Test. So if my class has a no args constructor, and only runs once everything works beautiful.
For example, for my no args test, i can just reference my class in the testing xml config and it will run no problems.
The issue is when my tests are dynamically ran, which from inception of the our testing framework was done by constructor args.

For example I have a test called test1, where the constructor take an enum that drives the tests experience.
Each test needs its own attributes (webdriver/selenium/etc) which are provided fresh with every instance of my abstract class.
So I need another instance of the test class.

Now I have gotten a factory to execute my tests successfully any everything works great except one thing.
I can't select specific tests cases. IE. the factory is loaded up with 10 instances of my test, without a code change I can't select one test case.
I could create another class per test case, but that causes a bunch of class bloat.

More concise but still dirty in my own opinion I could extend my test clases and provide the constructor arg for each of test cases for the super, and then have a no args
constructor for my child class that testng would have no issue running. 
This causes a ton of class bloat.
public class test1BestCompany extends test1{
 
public test1BestCompany() {
 
super(Affiliates.BESTCOMPANY);
 
}
}



@Test
public void runTestBestCompany(){
   
new test1(Affiliates.BESTCOMPANY).run();
}
@Test
public void runTestWrongCompany(){
   
new test1(Affiliates.WRONGCOMPANY).run();
}


There has to be something better than the crazy solutions I have came up with.
Thanks,
Joe

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Difficulties leveraging Testng, due to test design

⇜Krishnan Mahadevan⇝

Joe,

 

>>>>> - I couldn't figure out a way to use a pre-instantiated instance of "acomplexclass" via the @InjectParameters

 

Why not just make use of keys in the @InjectedParameters, which could perhaps query a Object bag that you talk of wherein instances are already pre instantiated. That way your base class just queries this Object bag to get the instance. If the instance doesn’t exist, then the object bag could create one and store it as well (Similar to what Spring does).

 

>>>>> Every time I want to create a new test with that requires a new class in its constructor I will have to duplicate code in the @InjectedParameters and/or getParametersToInject on Abstract Validator.

 

Yes you would. Not sure how else can the binding be done. What constructor are you talking about? The one in the base class ? I left that as is in the sample, only because your sample had it there and you hadn’t added any context in your problem statement. Also TestNG supports Guice Injection as well. Perhaps you could explore some of those capabilities and see how they can be blended in to take care of your Object instantiation perhaps.

 

Lastly the sample that I shared was only meant to give you an idea on how you could proceed further and wasn’t meant to be a full fledged solution that can be consumed as is. Obviously there is scope for a lot of improvisations, but since I don’t have visibility to the specifics of your problem I stuck to a basic example.

 

I hope that you can leverage and use all the good features of TestNG using the sample that I shared!

Good luck.

 

PS: I am going to post the same answer to your stackoverflow question. Please help accept it, if it atleast answered your question.

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

From: <[hidden email]> on behalf of Joe DeSantis <[hidden email]>
Reply-To: <[hidden email]>
Date: Friday, May 4, 2018 at 1:33 AM
To: testng-users <[hidden email]>
Subject: [testng-users] Re: Difficulties leveraging Testng, due to test design

 

Krishnan Mahadevan,

 

Thanks for the continued help.

I was able to get your example running, and pushed it up to my test repo.

There did seem to be issues with the approach though:

- I couldn't figure out a way to use a pre-instantiated instance of "acomplexclass" via the @InjectParameters

- Also, I know it wasn't clear in my minimal example, but different tests (that all extent my AbstractValidator2) have different constructors.

 

For example one of my most extreme tests classes has a constructor like the following:

String url, WebDriver driver, String partnerToRequest, IPRequester requester, boolean featuretoggleflag
Others take a varying range of different arguments (numerous to none): enums, booleans, custom class instances, etc.
 

Every time I want to create a new test with that requires a new class in its constructor I will have to duplicate code in the @InjectedParameters and/or getParametersToInject on Abstract Validator.

 

On the side, I attempted to see if I could get the functionality I was looking for using Junit 5.

The running of individual tests did seem easy to configure, I am now trying to figure out how to create suites(not as much of a first class consideration as testng) and run in parallel.

 

 

 

 

Each Test class,

On Friday, April 27, 2018 at 7:54:17 PM UTC-4, Joe DeSantis wrote:

All of my test cases extend off of a abstract class that has a bunch of methods: setup, run, teardown etc (this was built prior to testng implementation).

The issue is all of my tests require a new instance of the test class, which would work great with junit, but has caused me alot of pain with testng.

 

I have annotiated my base class run method with @Test. So if my class has a no args constructor, and only runs once everything works beautiful.

For example, for my no args test, i can just reference my class in the testing xml config and it will run no problems.

The issue is when my tests are dynamically ran, which from inception of the our testing framework was done by constructor args.

 

For example I have a test called test1, where the constructor take an enum that drives the tests experience.

Each test needs its own attributes (webdriver/selenium/etc) which are provided fresh with every instance of my abstract class.

So I need another instance of the test class.

 

Now I have gotten a factory to execute my tests successfully any everything works great except one thing.

I can't select specific tests cases. IE. the factory is loaded up with 10 instances of my test, without a code change I can't select one test case.

I could create another class per test case, but that causes a bunch of class bloat.

 

More concise but still dirty in my own opinion I could extend my test clases and provide the constructor arg for each of test cases for the super, and then have a no args

constructor for my child class that testng would have no issue running. 

This causes a ton of class bloat.

public class test1BestCompany extends test1{
 
public test1BestCompany() {
 
super(Affiliates.BESTCOMPANY);
 
}
}
 

 

 

@Test
public void runTestBestCompany(){
   
new test1(Affiliates.BESTCOMPANY).run();
}
@Test
public void runTestWrongCompany(){
   
new test1(Affiliates.WRONGCOMPANY).run();
}

 

There has to be something better than the crazy solutions I have came up with.

Thanks,

Joe

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
[hidden email].
To post to this group, send email to
[hidden email].
Visit this group at
https://groups.google.com/group/testng-users.
For more options, visit
https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Difficulties leveraging Testng, due to test design

Joe DeSantis


My end analysis is that there is no clean way to do what I was attempting to do.

If I had to simplify what I was attempting to do it would be the following:
Have a suite of multiple different test classes, each of which when provided different constructor arguments where completely different tests.
At face value there is a lot of TestNG capabilities that seem like they would be able to solve it, but when looking at the complexities they all feel a tad short. 

All solutions had too many draw backs, so I approached it from another angle, an example of something I was thinking I have uploaded to my test bed repository.
https://github.com/Warfront1/TestNG-Create-Individual-Instances/tree/master/src/test/java/testngImplementation/testCreationWorkAround5

Interesting to note that even in this design due to the fact that I need to run in parallel, and will be using a single class for multiple test cases(now test methods),
I am forced to use things such as ThreadLocal, or pass generators/provider that each thread would be able to utilize in order to get instances of necessary dependencies.
All of which could most likely be avoided if each test case had the ability to use a fresh instance of the test class. (similar to JUnit)

Thoughts,
Joe


On Thursday, May 3, 2018 at 10:50:48 PM UTC-4, Krishnan Mahadevan wrote:

Joe,

 

>>>>> - I couldn't figure out a way to use a pre-instantiated instance of "acomplexclass" via the @InjectParameters

 

Why not just make use of keys in the @InjectedParameters, which could perhaps query a Object bag that you talk of wherein instances are already pre instantiated. That way your base class just queries this Object bag to get the instance. If the instance doesn’t exist, then the object bag could create one and store it as well (Similar to what Spring does).

 

>>>>> Every time I want to create a new test with that requires a new class in its constructor I will have to duplicate code in the @InjectedParameters and/or getParametersToInject on Abstract Validator.

 

Yes you would. Not sure how else can the binding be done. What constructor are you talking about? The one in the base class ? I left that as is in the sample, only because your sample had it there and you hadn’t added any context in your problem statement. Also TestNG supports Guice Injection as well. Perhaps you could explore some of those capabilities and see how they can be blended in to take care of your Object instantiation perhaps.

 

Lastly the sample that I shared was only meant to give you an idea on how you could proceed further and wasn’t meant to be a full fledged solution that can be consumed as is. Obviously there is scope for a lot of improvisations, but since I don’t have visibility to the specifics of your problem I stuck to a basic example.

 

I hope that you can leverage and use all the good features of TestNG using the sample that I shared!

Good luck.

 

PS: I am going to post the same answer to your stackoverflow question. Please help accept it, if it atleast answered your question.

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

From: <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="mtGD7jbhCQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...> on behalf of Joe DeSantis <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="mtGD7jbhCQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">desan...@...>
Reply-To: <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="mtGD7jbhCQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Date: Friday, May 4, 2018 at 1:33 AM
To: testng-users <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="mtGD7jbhCQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Subject: [testng-users] Re: Difficulties leveraging Testng, due to test design

 

Krishnan Mahadevan,

 

Thanks for the continued help.

I was able to get your example running, and pushed it up to my test repo.

There did seem to be issues with the approach though:

- I couldn't figure out a way to use a pre-instantiated instance of "acomplexclass" via the @InjectParameters

- Also, I know it wasn't clear in my minimal example, but different tests (that all extent my AbstractValidator2) have different constructors.

 

For example one of my most extreme tests classes has a constructor like the following:

String url, WebDriver driver, String partnerToRequest, IPRequester requester, boolean featuretoggleflag
Others take a varying range of different arguments (numerous to none): enums, booleans, custom class instances, etc.
 

Every time I want to create a new test with that requires a new class in its constructor I will have to duplicate code in the @InjectedParameters and/or getParametersToInject on Abstract Validator.

 

On the side, I attempted to see if I could get the functionality I was looking for using Junit 5.

The running of individual tests did seem easy to configure, I am now trying to figure out how to create suites(not as much of a first class consideration as testng) and run in parallel.

 

 

 

 

Each Test class,

On Friday, April 27, 2018 at 7:54:17 PM UTC-4, Joe DeSantis wrote:

All of my test cases extend off of a abstract class that has a bunch of methods: setup, run, teardown etc (this was built prior to testng implementation).

The issue is all of my tests require a new instance of the test class, which would work great with junit, but has caused me alot of pain with testng.

 

I have annotiated my base class run method with @Test. So if my class has a no args constructor, and only runs once everything works beautiful.

For example, for my no args test, i can just reference my class in the testing xml config and it will run no problems.

The issue is when my tests are dynamically ran, which from inception of the our testing framework was done by constructor args.

 

For example I have a test called test1, where the constructor take an enum that drives the tests experience.

Each test needs its own attributes (webdriver/selenium/etc) which are provided fresh with every instance of my abstract class.

So I need another instance of the test class.

 

Now I have gotten a factory to execute my tests successfully any everything works great except one thing.

I can't select specific tests cases. IE. the factory is loaded up with 10 instances of my test, without a code change I can't select one test case.

I could create another class per test case, but that causes a bunch of class bloat.

 

More concise but still dirty in my own opinion I could extend my test clases and provide the constructor arg for each of test cases for the super, and then have a no args

constructor for my child class that testng would have no issue running. 

This causes a ton of class bloat.

public class test1BestCompany extends test1{
 
public test1BestCompany() {
 
super(Affiliates.BESTCOMPANY);
 
}
}
 

 

 

@Test
public void runTestBestCompany(){
   
new test1(Affiliates.BESTCOMPANY).run();
}
@Test
public void runTestWrongCompany(){
   
new test1(Affiliates.WRONGCOMPANY).run();
}

 

There has to be something better than the crazy solutions I have came up with.

Thanks,

Joe

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
<a href="javascript:" target="_blank" gdf-obfuscated-mailto="mtGD7jbhCQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng-users+unsubscribe@googlegroups.com.
To post to this group, send email to
<a href="javascript:" target="_blank" gdf-obfuscated-mailto="mtGD7jbhCQAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng-users@....
Visit this group at
<a href="https://groups.google.com/group/testng-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit
<a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Difficulties leveraging Testng, due to test design

Joe DeSantis
Krishnan,

After the fact of writing approach 5, I found an article on your blog: https://rationaleemotions.wordpress.com/2013/07/31/parallel-webdriver-executions-using-testng/

I also created a approach 6, which follows your blog making a listener approach:
https://github.com/Warfront1/TestNG-Create-Individual-Instances/tree/master/src/test/java/testngImplementation/testCreationWorkAround6

I am interested in why you choose to go the listener route vs using before and after method?
In my example 5 I was able to get similar functionality using inheritance and primarily before and after method annotations.

One key issue I had with your blog post example was that guice was no longer easy to use ( I am not aware of way to inject into listeners in a clean way).
In either my spin on it or your blog post you are still limited to this manager thread local design, which usually forces you to have to create instances yourself anyway (via a factory in your example)

Warfront1


On Monday, May 14, 2018 at 5:48:12 PM UTC-4, Joe DeSantis wrote:


My end analysis is that there is no clean way to do what I was attempting to do.

If I had to simplify what I was attempting to do it would be the following:
Have a suite of multiple different test classes, each of which when provided different constructor arguments where completely different tests.
At face value there is a lot of TestNG capabilities that seem like they would be able to solve it, but when looking at the complexities they all feel a tad short. 

All solutions had too many draw backs, so I approached it from another angle, an example of something I was thinking I have uploaded to my test bed repository.
<a href="https://github.com/Warfront1/TestNG-Create-Individual-Instances/tree/master/src/test/java/testngImplementation/testCreationWorkAround5" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FWarfront1%2FTestNG-Create-Individual-Instances%2Ftree%2Fmaster%2Fsrc%2Ftest%2Fjava%2FtestngImplementation%2FtestCreationWorkAround5\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGlXrA-4Ze9vEcboeFpEUHa1R5OBQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FWarfront1%2FTestNG-Create-Individual-Instances%2Ftree%2Fmaster%2Fsrc%2Ftest%2Fjava%2FtestngImplementation%2FtestCreationWorkAround5\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGlXrA-4Ze9vEcboeFpEUHa1R5OBQ&#39;;return true;">https://github.com/Warfront1/TestNG-Create-Individual-Instances/tree/master/src/test/java/testngImplementation/testCreationWorkAround5

Interesting to note that even in this design due to the fact that I need to run in parallel, and will be using a single class for multiple test cases(now test methods),
I am forced to use things such as ThreadLocal, or pass generators/provider that each thread would be able to utilize in order to get instances of necessary dependencies.
All of which could most likely be avoided if each test case had the ability to use a fresh instance of the test class. (similar to JUnit)

Thoughts,
Joe


On Thursday, May 3, 2018 at 10:50:48 PM UTC-4, Krishnan Mahadevan wrote:

Joe,

 

>>>>> - I couldn't figure out a way to use a pre-instantiated instance of "acomplexclass" via the @InjectParameters

 

Why not just make use of keys in the @InjectedParameters, which could perhaps query a Object bag that you talk of wherein instances are already pre instantiated. That way your base class just queries this Object bag to get the instance. If the instance doesn’t exist, then the object bag could create one and store it as well (Similar to what Spring does).

 

>>>>> Every time I want to create a new test with that requires a new class in its constructor I will have to duplicate code in the @InjectedParameters and/or getParametersToInject on Abstract Validator.

 

Yes you would. Not sure how else can the binding be done. What constructor are you talking about? The one in the base class ? I left that as is in the sample, only because your sample had it there and you hadn’t added any context in your problem statement. Also TestNG supports Guice Injection as well. Perhaps you could explore some of those capabilities and see how they can be blended in to take care of your Object instantiation perhaps.

 

Lastly the sample that I shared was only meant to give you an idea on how you could proceed further and wasn’t meant to be a full fledged solution that can be consumed as is. Obviously there is scope for a lot of improvisations, but since I don’t have visibility to the specifics of your problem I stuck to a basic example.

 

I hope that you can leverage and use all the good features of TestNG using the sample that I shared!

Good luck.

 

PS: I am going to post the same answer to your stackoverflow question. Please help accept it, if it atleast answered your question.

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

From: <[hidden email]> on behalf of Joe DeSantis <[hidden email]>
Reply-To: <[hidden email]>
Date: Friday, May 4, 2018 at 1:33 AM
To: testng-users <[hidden email]>
Subject: [testng-users] Re: Difficulties leveraging Testng, due to test design

 

Krishnan Mahadevan,

 

Thanks for the continued help.

I was able to get your example running, and pushed it up to my test repo.

There did seem to be issues with the approach though:

- I couldn't figure out a way to use a pre-instantiated instance of "acomplexclass" via the @InjectParameters

- Also, I know it wasn't clear in my minimal example, but different tests (that all extent my AbstractValidator2) have different constructors.

 

For example one of my most extreme tests classes has a constructor like the following:

String url, WebDriver driver, String partnerToRequest, IPRequester requester, boolean featuretoggleflag
Others take a varying range of different arguments (numerous to none): enums, booleans, custom class instances, etc.
 

Every time I want to create a new test with that requires a new class in its constructor I will have to duplicate code in the @InjectedParameters and/or getParametersToInject on Abstract Validator.

 

On the side, I attempted to see if I could get the functionality I was looking for using Junit 5.

The running of individual tests did seem easy to configure, I am now trying to figure out how to create suites(not as much of a first class consideration as testng) and run in parallel.

 

 

 

 

Each Test class,

On Friday, April 27, 2018 at 7:54:17 PM UTC-4, Joe DeSantis wrote:

All of my test cases extend off of a abstract class that has a bunch of methods: setup, run, teardown etc (this was built prior to testng implementation).

The issue is all of my tests require a new instance of the test class, which would work great with junit, but has caused me alot of pain with testng.

 

I have annotiated my base class run method with @Test. So if my class has a no args constructor, and only runs once everything works beautiful.

For example, for my no args test, i can just reference my class in the testing xml config and it will run no problems.

The issue is when my tests are dynamically ran, which from inception of the our testing framework was done by constructor args.

 

For example I have a test called test1, where the constructor take an enum that drives the tests experience.

Each test needs its own attributes (webdriver/selenium/etc) which are provided fresh with every instance of my abstract class.

So I need another instance of the test class.

 

Now I have gotten a factory to execute my tests successfully any everything works great except one thing.

I can't select specific tests cases. IE. the factory is loaded up with 10 instances of my test, without a code change I can't select one test case.

I could create another class per test case, but that causes a bunch of class bloat.

 

More concise but still dirty in my own opinion I could extend my test clases and provide the constructor arg for each of test cases for the super, and then have a no args

constructor for my child class that testng would have no issue running. 

This causes a ton of class bloat.

public class test1BestCompany extends test1{
 
public test1BestCompany() {
 
super(Affiliates.BESTCOMPANY);
 
}
}
 

 

 

@Test
public void runTestBestCompany(){
   
new test1(Affiliates.BESTCOMPANY).run();
}
@Test
public void runTestWrongCompany(){
   
new test1(Affiliates.WRONGCOMPANY).run();
}

 

There has to be something better than the crazy solutions I have came up with.

Thanks,

Joe

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
testng-users+unsubscribe@googlegroups.com.
To post to this group, send email to
[hidden email].
Visit this group at
<a href="https://groups.google.com/group/testng-users" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit
<a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Difficulties leveraging Testng, due to test design

⇜Krishnan Mahadevan⇝

Joe,

 

>>> I am interested in why you choose to go the listener route vs using before and after method?

 

I chose not to leverage a base class with the Before/After method because of inheritance. What if my test class also had to extend some other class? Having all of them extend a base class would prevent people from doing it.

 

>>> One key issue I had with your blog post example was that guice was no longer easy to use (I am not aware of way to inject into listeners in a clean way).

 

My experience with Guice is very limited and I have mostly explored it only on need basis and when trying to answer people’s questions as blog posts.

Not sure what you would want to inject into a listener?

 

Here’s a theory: Maybe you can wire in a parent guice module via your suite xml file, which could then be used as a reference in org.testng.ITestNGListenerFactory#createListener implementation (and you can try wiring in an implementation of org.testng.ITestNGListenerFactory). You can refer to this blog of mine, to learn more about the TestNG listener factory.

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

From: <[hidden email]> on behalf of Joe DeSantis <[hidden email]>
Reply-To: <[hidden email]>
Date: Thursday, May 17, 2018 at 10:00 AM
To: testng-users <[hidden email]>
Subject: Re: [testng-users] Re: Difficulties leveraging Testng, due to test design

 

Krishnan,

 

After the fact of writing approach 5, I found an article on your blog: https://rationaleemotions.wordpress.com/2013/07/31/parallel-webdriver-executions-using-testng/

 

I also created a approach 6, which follows your blog making a listener approach:

https://github.com/Warfront1/TestNG-Create-Individual-Instances/tree/master/src/test/java/testngImplementation/testCreationWorkAround6

 

I am interested in why you choose to go the listener route vs using before and after method?

In my example 5 I was able to get similar functionality using inheritance and primarily before and after method annotations.

 

One key issue I had with your blog post example was that guice was no longer easy to use ( I am not aware of way to inject into listeners in a clean way).

In either my spin on it or your blog post you are still limited to this manager thread local design, which usually forces you to have to create instances yourself anyway (via a factory in your example)

 

Warfront1



On Monday, May 14, 2018 at 5:48:12 PM UTC-4, Joe DeSantis wrote:

 

 

My end analysis is that there is no clean way to do what I was attempting to do.

 

If I had to simplify what I was attempting to do it would be the following:

Have a suite of multiple different test classes, each of which when provided different constructor arguments where completely different tests.

At face value there is a lot of TestNG capabilities that seem like they would be able to solve it, but when looking at the complexities they all feel a tad short. 

 

All solutions had too many draw backs, so I approached it from another angle, an example of something I was thinking I have uploaded to my test bed repository.

 

Interesting to note that even in this design due to the fact that I need to run in parallel, and will be using a single class for multiple test cases(now test methods),

I am forced to use things such as ThreadLocal, or pass generators/provider that each thread would be able to utilize in order to get instances of necessary dependencies.

All of which could most likely be avoided if each test case had the ability to use a fresh instance of the test class. (similar to JUnit)

 

Thoughts,

Joe



On Thursday, May 3, 2018 at 10:50:48 PM UTC-4, Krishnan Mahadevan wrote:

Joe,

 

>>>>> - I couldn't figure out a way to use a pre-instantiated instance of "acomplexclass" via the @InjectParameters

 

Why not just make use of keys in the @InjectedParameters, which could perhaps query a Object bag that you talk of wherein instances are already pre instantiated. That way your base class just queries this Object bag to get the instance. If the instance doesn’t exist, then the object bag could create one and store it as well (Similar to what Spring does).

 

>>>>> Every time I want to create a new test with that requires a new class in its constructor I will have to duplicate code in the @InjectedParameters and/or getParametersToInject on Abstract Validator.

 

Yes you would. Not sure how else can the binding be done. What constructor are you talking about? The one in the base class ? I left that as is in the sample, only because your sample had it there and you hadn’t added any context in your problem statement. Also TestNG supports Guice Injection as well. Perhaps you could explore some of those capabilities and see how they can be blended in to take care of your Object instantiation perhaps.

 

Lastly the sample that I shared was only meant to give you an idea on how you could proceed further and wasn’t meant to be a full fledged solution that can be consumed as is. Obviously there is scope for a lot of improvisations, but since I don’t have visibility to the specifics of your problem I stuck to a basic example.

 

I hope that you can leverage and use all the good features of TestNG using the sample that I shared!

Good luck.

 

PS: I am going to post the same answer to your stackoverflow question. Please help accept it, if it atleast answered your question.

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

From: <[hidden email]> on behalf of Joe DeSantis <[hidden email]>
Reply-To: <[hidden email]>
Date: Friday, May 4, 2018 at 1:33 AM
To: testng-users <[hidden email]>
Subject: [testng-users] Re: Difficulties leveraging Testng, due to test design

 

Krishnan Mahadevan,

 

Thanks for the continued help.

I was able to get your example running, and pushed it up to my test repo.

There did seem to be issues with the approach though:

- I couldn't figure out a way to use a pre-instantiated instance of "acomplexclass" via the @InjectParameters

- Also, I know it wasn't clear in my minimal example, but different tests (that all extent my AbstractValidator2) have different constructors.

 

For example one of my most extreme tests classes has a constructor like the following:

String url, WebDriver driver, String partnerToRequest, IPRequester requester, boolean featuretoggleflag
Others take a varying range of different arguments (numerous to none): enums, booleans, custom class instances, etc.
 

Every time I want to create a new test with that requires a new class in its constructor I will have to duplicate code in the @InjectedParameters and/or getParametersToInject on Abstract Validator.

 

On the side, I attempted to see if I could get the functionality I was looking for using Junit 5.

The running of individual tests did seem easy to configure, I am now trying to figure out how to create suites(not as much of a first class consideration as testng) and run in parallel.

 

 

 

 

Each Test class,

On Friday, April 27, 2018 at 7:54:17 PM UTC-4, Joe DeSantis wrote:

All of my test cases extend off of a abstract class that has a bunch of methods: setup, run, teardown etc (this was built prior to testng implementation).

The issue is all of my tests require a new instance of the test class, which would work great with junit, but has caused me alot of pain with testng.

 

I have annotiated my base class run method with @Test. So if my class has a no args constructor, and only runs once everything works beautiful.

For example, for my no args test, i can just reference my class in the testing xml config and it will run no problems.

The issue is when my tests are dynamically ran, which from inception of the our testing framework was done by constructor args.

 

For example I have a test called test1, where the constructor take an enum that drives the tests experience.

Each test needs its own attributes (webdriver/selenium/etc) which are provided fresh with every instance of my abstract class.

So I need another instance of the test class.

 

Now I have gotten a factory to execute my tests successfully any everything works great except one thing.

I can't select specific tests cases. IE. the factory is loaded up with 10 instances of my test, without a code change I can't select one test case.

I could create another class per test case, but that causes a bunch of class bloat.

 

More concise but still dirty in my own opinion I could extend my test clases and provide the constructor arg for each of test cases for the super, and then have a no args

constructor for my child class that testng would have no issue running. 

This causes a ton of class bloat.

public class test1BestCompany extends test1{
 
public test1BestCompany() {
 
super(Affiliates.BESTCOMPANY);
 
}
}
 

 

 

@Test
public void runTestBestCompany(){
   
new test1(Affiliates.BESTCOMPANY).run();
}
@Test
public void runTestWrongCompany(){
   
new test1(Affiliates.WRONGCOMPANY).run();
}

 

There has to be something better than the crazy solutions I have came up with.

Thanks,

Joe

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at
https://groups.google.com/group/testng-users.
For more options, visit
https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
[hidden email].
To post to this group, send email to
[hidden email].
Visit this group at
https://groups.google.com/group/testng-users.
For more options, visit
https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.