I'm trying to use for the first time TestNG with #Factory and for me doesn't work, I'll say you why.
I have a class called Extend in which I have some tests, "launch site", "login", "check if the useris in his own dashboard" and so on and I wanted that for all datas passed from the factory the order of theese test are always the same "launch site">>"login">>"check user is in his dashboard">>"logout" ok? So I have the following extend.xml file and classes:
<suite name="ExtendFactory" group-by-instances="true">
<test name="Factory" preserve-order="true" group-by-instances="true">
<classes>
<class name="net.whaooo.ExtendFactory">
<methods>
<include name="launchSite"></include>
<include name="loginTest" />
<include name="userIsInHisOwnDashboardTest" />
<include name="logoutTest" />
</methods>
</class>
</classes>
</test>
</suite>
Extend class:
public class Extend extends BaseTest{
protected static FirefoxDriver driver;
private String a_driver;
private String password;
public Extend(String a_driver, String pwd){
this.a_driver = a_driver;
this.password = pwd;
}
#BeforeTest
public void stDriver() {
DesiredCapabilities caps = DesiredCapabilities.firefox(); caps.setCapability(CapabilityType.ForSeleniumServer.ENSURING_CLEAN_SESSION, true);
driver = new FirefoxDriver(caps);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
#AfterTest
public void stopDriver() {
driver.close();
}
#Test
public void launch() {
launchSite(driver);
}
#Test (description = "Enter a valid login as driver")
public void loginTest() {
login(driver, a_driver, password);
}
#Test (description = "Check the driver is in his own dashboard")
public void userIsInHisOwnDashboardTest(){
userIsInHisOwnDashboardTest(driver, a_driver, password);
}
#Test(description="logout")
public void logout(){
logoutTest(driver);
}
}
Semplified Factory:
public class ExtendFactory {
#Factory
public Object[] createInstances() {
Object[] result = new Object[2];
result[0] = new Extend("test1#test.com","tester");
result[1] = new Extend("test2#test.com","tester");
return result;
}
}
But my problem is that the order in which the tests are launched doesn't follow the one specified in the xml file even if I insert the clause preserve-order="true" group-by-instances="true", I tryed also with order-by-instances="true". Can anyone help me?
I see many issues... first of all #Factory with group-by-instance="true" messes up whole test (it executes just one instance and only non-dependent methods).
#Factory works without group-by-instance but it executes all non-dependent methods first irrespective of number of instances. Eg.. Class A {#Test public void a() {} #Test(dependsOnMethod="a") public void b() {}}... along with #Factory that returns two instances.. then the execution is ref1.a, ref2.a, ref1.b, ref2.b. this has serious issue.. say class A uses large amount of memory then sure it will run out before executing all.
ps: not sure if it is eclipse issue. I am using testng 6.8.1
ps2: seems like testng intends for regression.. but it is still not there.. nor its regression (#Factory) is supported by its own classes (like #Listeners who will read only #Parameters.. but #Factory cannot set same) or by third party.
I think what you need to use is dependsOnMethods in your testcases, coz the flow that you mention, if the first method doesn't execute, there is no point in executing the second testcase. i.e. if "launch site" fails, there's no need to execute "login". This would also ensure order of execution. Check out Dependent Methods
I've been using the
#Test(dependsOnMethods = "TestName")
Where "TestName" is the prerequisite test to run. So for your login test, it should have the following annotation:
#Test(dependsOnMethods = "launchSite")
I'm running 9 tests in a row, and since adding the dependsOnMethods, all have ran in order with no issue
Thank you for your answer, I ended up to use a #Factory specifing "order-by-instances="true"" and than in the dynamic object I insert the dependencies!
Using depends in the TestClass file is not a solution as the functions which are not dependent on any other functions are still been executed randomly.
I need to execute the Test Cases in the order which i have mentioned. This can be achieved using "preserve-order" when executed using TestNG but it fails when grouping is used in TestNG.
If anyone can help in this concern, please revert.
Related
I have an Apache Camel application, which uses a Choice with a Predicate. How can I test the predicate without an integration test?
Code
#SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
#Bean
public EndpointRouteBuilder route() {
return new EndpointRouteBuilder() {
#Override
public void configure() throws Exception {
from(file("d:/tmp/camel/"))
.choice()
.when(jsonpath("$[?(#.status == 0)]"))
.log("ok")
.otherwise()
.log("not ok");
}
};
}
}
Research
I read Test JUnit5, but it looks like an integration test. However, I don't want to test a full route.
I read Test Spring JUnit5, but it is an integration test.
Question
How can I extract the predicate jsonpath("$[?(#.status == 0)]") and test it isolated in an unit test with JUnit 5?
Might be hard to accomplish this without a CamelContext. I'd probably approach this with Camel's excellent mocking and stubbing utilities. But if you really just want to isolate the jsonpath expression, you could try something like this:
JsonPathExpression exp = new JsonPathExpression("$[?(#.status == 0)]");
Exchange exchange = new DefaultExchange(context);
final Predicate predicate = exp.createPredicate(context);
exchange.getIn().setBody("{ \"status\": 0 }");
final boolean matches = predicate.matches(exchange);
assertTrue(matches);
Note that you'll still need a CamelContext for this. Typically you'd get it by having the test class extend CamelTestSupport, or if you're in a spring environment, spring can autowire it: #Autowired CamelContext camelContext;
Edit: If you just want to test the JsonPath expression outside of Camel:
String jsonPath = "$[?(#.status == 0)]";
String json = "{ \"status\": 0 }";
DocumentContext jsonContext = JsonPath.parse(json);
JSONArray result = jsonContext.read(jsonPath);
assertEquals(1, result.size());
My opinion (you'll probably get 100 more ;-)
Separate that route into another class by itself that can be loaded into the Spring context later.
Use CamelTestSupport to load just Camel (not Spring) in JUnit.
Use Camel "advice" to change "from" to a direct, or create a file (in your test) to exercise the test case you want (once with each branch of the choice.
Again with "advice" change the log to mocks - then after running the file/message you want check to see if the correct mock got a message and the other did not.
I'm writing a unit test case for my functionality using Groovy. But, however I'm not able to configure the values that are available in the class. The values are configured in my yaml file.
Here is my code
class UpdateServiceImplTest extends Specification {
DataSourceRestTemplateConfig dataSourceRestTemplateConfig
def setup() {
dataSourceRestTemplateConfig= Mock(DataSourceRestTemplateConfig )
}
}
This DataSourceRestTemplateConfig class is using some properties, which is coming as null while executing the test
public class DataSourceRestTemplateConfig {
#Autowired
RestTemplate restTemplate;
#Value("${datasource.auth.username}")
private String userNameNew;
#Value("${datasource.auth.password}")
private String passwordNew;
// Method to call DB here
}
The above values are coming as null when I evaluate the expression. Are there any other configurations am I missing?
Any ideas would be greatly helpful to me.
I am using Rhino.Mocks and Structure map to help unit test my code. I have several tests that pass when they are ran by themselves, but when ran as a group fail to pass. The setup code for these unit tests is:
[TestInitialize()]
public void Setup()
{
ObjectFactory.Initialize(x =>
{
x.For(IManager)().Use(Handler)();
});
}
In my tests, I stub out this interface and call the method.
[TestMethod]
public void AreMultiple_Test()
{
var mackIManager = MockRepository.GenerateMock<IManager>();
mackIManager.Stub(u => u.GetTwoUserName(Arg<int>.Is.Anything)).Return(null);
ObjectFactory.Inject(typeof(IManager), mackIManager);
StepAdditionalActionBase actionBase = new StepAdditionalActionBase();
bool areMultiple = actionBase.AreMultiple(new WorkOrder { Id = "123" });
Assert.IsFalse(areMultiple);
}
Test Method 2
[TestMethod]
public void AreMultiple_Test()
{
var mackIManager = MockRepository.GenerateMock<IManager>();
mackIManager.Stub(u => u.GetTwoUserName(Arg<int>.Is.Anything)).Return("123");
ObjectFactory.Inject(typeof(IManager), mackIManager);
StepAdditionalActionBase actionBase = new StepAdditionalActionBase();
bool areMultiple = actionBase.AreMultiple(new WorkOrder { Id = "123" });
Assert.IsTrue(areMultiple);
}
This is unit testing the following code.
public bool AreMultiple(WorkOrder workOrder)
{
string secondUser = _handler.GetTwoUserName(_workflowManager.GetNumberForProject(workOrder.Id));
if (String.IsNullOrEmpty(secondUser ))
{
return false;
}
return true;
}
When I run them by themselves, they work fine. When I run them together, the first passes and the second fails. When I debug the second one, I find that that the return value in the Stubbed method is still coming back as null. How do I get this to use the new Stubbed method.
UPDATE.
I am using StructureMap as my container. From what I have been able to find, the following code is what is used to dispose of the container I got it from this link. When I added this, the test still fail when ran together, but pass when ran individually.
[TestCleanup()]
public void TestCLeanup()
{
ObjectFactory.Container.Dispose();
}
The tests work one by one but fails if run all together. The problem should be in the common part which is being shared across the tests making them dependent from each other. In this particular case that is static ObjectFactory which is nothing else but a Service Locator (anti-pattern).
In the tests, you mock the IManager interface and register it in the ObjectFactory:
ObjectFactory.Inject(typeof(IManager), mackIManager);
Then the SUT uses the ObjectFactory service locator to resolve and use the mocked interface (_handler field):
string secondUser = _handler.GetTwoUserName(...)
I suspect the first test registers the _handler and never clean it up properly, so that the same instance appears in the second test. You should reset the ObjectFactory between tests following the Register Resolve Release pattern.
Another (preferable) option is to refactor your SUT to receive the IManager handler dependency explicitly via constructor. That would simplify both SUT and tests moving the ObjectFactory configuration to the Composition Root.
Today I'm working on a class with two static methods which have same name, different parameter types. When I try to mock one of the methods, I encounter this problem.
This is the class to be mocked:
//RequestUtil.java, I want to mock the second config method
public class RequestUtil {
public static void config(String request, List parameters){}
public static void config(HttpServletRequest request, List parameters){}
}
This is the test class:
//RequestUtilTest.java
#RunWith(PowerMockRunner.class)
#PrepareForTest(RequestUtil.class)
public class RequestUtilTest {
//this test will throw NullPointException
#Test
public void testConfig() throws Exception {
mockStatic(RequestUtil.class);
doNothing().when(RequestUtil.class, "config", any(HttpServletRequest.class), anyList());
}
}
Run this test, and it will throw exceptions:
java.lang.NullPointerException
at java.lang.Class.isAssignableFrom(Native Method)
at org.powermock.reflect.internal.WhiteboxImpl.checkIfParameterTypesAreSame(WhiteboxImpl.java:2432)
at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1934)
at org.powermock.reflect.internal.WhiteboxImpl.getBestMethodCandidate(WhiteboxImpl.java:1025)
at org.powermock.reflect.internal.WhiteboxImpl.findMethodOrThrowException(WhiteboxImpl.java:948)
at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:882)
at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:859)
at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:466)
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:106)
...
This exception is caused by:
doNothing().when(RequestUtil.class, "config", any(HttpServletRequest.class), anyList());
However, if I mock the first config method, that means, replace this line with:
doNothing().when(RequestUtil.class, "config", anyString(), anyList());
everything is Ok.
The order of the config methods in the defination of RequestUtil class has nothing to do with this issue. No matter config(HttpServletRequest, List) is the first or second config method of RequestUtil, the mock of config(HttpServletRequest, List) will be failure.
Also, if I modify the HttpServletRequest to another "simpler" type, such as int, this issue disappears.
It seems to be a bug of PowerMock, but I'm not sure. I searched Google and stackoverflow, but there are no post or discuss on this issue. So anyone can help me?
Test frameworks I use:
JUnit: 4.10
PowerMock: 1.5.4
Mockito: 1.9.5
It seems to be a PowerMock bug with overloaded methods.
You could bypass it by looking up the method object using the WhiteBox class, and mocking explicitly this method.
...
import org.powermock.reflect.Whitebox;
//RequestUtilTest.java
#RunWith(PowerMockRunner.class)
#PrepareForTest(RequestUtil.class)
public class RequestUtilTest {
//this test will throw NullPointException
#Test
public void testConfig() throws Exception {
mockStatic(RequestUtil.class);
Method method = Whitebox.getMethod(RequestUtil.class, "config", HttpServletRequest.class, List.class);
doNothing().when(RequestUtil.class, method);
}
}
A similar question have been asked previously on stackoverflow.
I'm starting to learn how to use PHPUnit to test the website I'm working on. The problem I'm running into is that I have five different user types defined and I need to be able to test every class with the different types. I currently have a user class and I would like to pass this to each function but I can't figure out how to pass this or test the different errors that could come back as being correct or not.
Edit: I should have said. I have a user class and I want to pass a different instance of this class to each unit test.
If your various user classes inherit from a parent user class, then I recommend you use the same inheritance structure for your test case classes.
Consider the following sample classes:
class User
{
public function commonFunctionality()
{
return 'Something';
}
public function modifiedFunctionality()
{
return 'One Thing';
}
}
class SpecialUser extends User
{
public function specialFunctionality()
{
return 'Nothing';
}
public function modifiedFunctionality()
{
return 'Another Thing';
}
}
You could do the following with your test case classes:
class Test_User extends PHPUnit_Framework_TestCase
{
public function create()
{
return new User();
}
public function testCommonFunctionality()
{
$user = $this->create();
$this->assertEquals('Something', $user->commonFunctionality);
}
public function testModifiedFunctionality()
{
$user = $this->create();
$this->assertEquals('One Thing', $user->commonFunctionality);
}
}
class Test_SpecialUser extends Test_User
{
public function create() {
return new SpecialUser();
}
public function testSpecialFunctionality()
{
$user = $this->create();
$this->assertEquals('Nothing', $user->commonFunctionality);
}
public function testModifiedFunctionality()
{
$user = $this->create();
$this->assertEquals('Another Thing', $user->commonFunctionality);
}
}
Because each test depends on a create method which you can override, and because the test methods are inherited from the parent test class, all tests for the parent class will be run against the child class, unless you override them to change the expected behavior.
This has worked great in my limited experience.
If you're looking to test the actual UI, you could try using something like Selenium (www.openqa.org). It lets you write the code in PHP (which I'm assuming would work with phpUnit) to drive the browser..
Another approach would be to have a common method that could be called by each test for your different user type. ie, something like 'ValidatePage', which you could then call from TestAdminUser or TestRegularUser and have the method simply perform the same basic validation of what you're expecting..
Just make sure you're not running into an anti-pattern here. Maybe you do too much work in the constructor? Or maybe these should be in fact different classes? Tests often give you clues about design of code. Listen to them.