DataProvider sequence in TestNG - selenium

Do we need to follow the same sequence in array object while using the dataObject
Eg: Code
#DataProvider(name = "test1")
public static Object[][] primeNumbers() {
return new Object[][] {{2, true}, {6, false}, {19, true}, {22, false}, {23, true}};
}
// This test will run 4 times since we have 5 parameters defined
#Test(dataProvider = "test1")
public void testPrimeNumberChecker(Integer inputNumber, Boolean expectedResult) {
System.out.println(inputNumber + " " + expectedResult);
Assert.assertEquals(expectedResult,
primeNumberChecker.validate(inputNumber));
}
In DataProvider Integer and Boolean are used and same sequence is used in testPrimeNumberChecker. Can I use only Boolean record in any of the function if I need.

Type, number and order/sequence of input parameters of #Test method must be same as passed by #DataProvider method.
Do we need to follow the same sequence in array object while using the dataObject
Here I assume by using you mean to passing the arguments in the #Test method. Answer of this is - Yes we need to follow the same sequence in array object while using the dataObject.
Example:
#Test(dataProvider = "test1")
public void testPrimeNumberChecker(Boolean expectedResult, Integer inputNumber) {
// your test method stuff
}
If you do not follow this you will get below exception:
java.lang.IllegalArgumentException: argument type mismatch
Can I use only Boolean record in any of the function if I need.
Here also I am assuming by use you mean to passing the arguments in the #Test method. Answer is - No, number of arguments matters.
Example:
#Test(dataProvider = "test1")
public void testPrimeNumberChecker(Boolean expectedResult) {
// your test method stuff
}
So if your #Test method has less or more number of input parameter(s) what your #DataProvider method passes, you will get below exception:
org.testng.TestNGException:
The data provider is trying to pass 2 parameters but the method yourpackage.YourTestClass#testPrimeNumberChecker takes 1

Related

test objects created inside a method jmockit

The method which I wanted to test looks like:
public void method1(String str) {
ParmaObjectRequest request = new ParmaObjectRequest(str);
this.instanceVar.save(request);
}
I wanted to test if this.instanceVar.save is called with an ParmaObjectRequest object with str value using jmockit.
The test case I have written looks like below and I am able to test that my method is called 1 times but not the parameter inside it.
#Test
public void testMethod1() {
new Expectations() {
{
this.instanceVar.save((ParmaObjectRequest) any);
times = 1;
}
};
testObject.method1("dummyString");
}
But I also wanted to test that this.instanceVar.save is called with object containing "dummyString".
In the Expectations block, change "this.instanceVar" to "testObject.instanceVar"

I am trying to implement multiGet operation in Spring on Redis, it throws me an error

I am trying to execute multiGet function in Spring on Redis. It throws me an error. I have implemented get function successfully but while implementing multiGet it asks me for a Collection as second parameter. I am not sure what to enter? Can someone please guide me here.
Here is my code for multiGet()
Method definition:
#Override
public User findById_MultiGet(String id) {
return (User)hashOperations.multiGet("USER", id);
}
Code In Controller :
#GetMapping("Map/MultiGet/{id}")
public User allMultiGet(#PathVariable("id") final String id) {
// MultiGet function
return userRepository.findById_MultiGet(id);
}
Error for above multiget method is multiget(Object, Collection) type not (String,String) type
Below code for Get function is working.
public User findById(String id) {
return (User)hashOperations.get("USER", id);
}
Code In Controller for Get function :
#GetMapping("Map/Get/{id}")
public User allGet(#PathVariable("id") final String id) {
// Get function
return userRepository.findById(id);
}
For multiGet the second parameter should be a Collection like a List (in case you want the values of the list returned as result on the same positions as their belonging keys in the input list) or a Set.
In your example this would be something like this:
List<Object> values = hashOperations.multiGet("USER", Arrays.asList("id", "name"));
Object id = values.get(0);
Object name = values.get(1);

How to retrive #Test method parameters in #DataProvider method?

I would like to retrieve parameters name of Test method in DataProvider method.
By using method.getParameterTypes() in DataProvider, I am able to get the class of param being passed in Test method, but I want the names.
#Test
public void TC_001(String userName, String passWord){
//code goes here
}
#DataProvider
public Object[][] testData(Method method){
//Here I want to get names of param of test method i.e. userName and passWord
}
This is required because using these names I can get the data from my Excel file
You can use reflection to get the parameters from the method to get the parameter names.
#DataProvider
public Object[][] testData(Method method){
String arg0 = method.getParameters()[0].getName();
// should be "userName" in your example test case
}
Note that the classes have to be compiled with -g:vars to include the parameter names in the debug information. Otherwise parameter names are named arg0, arg1, ... It appears that with the OpenJDK 8 this is the default.
To be less dependant on that fact and to avoid possible name confusion/conflicts I'd use a (custom) annotation that specifies the argument name:
Define an annotation:
#Retention(RUNTIME)
#Target(PARAMETER)
public #interface ParamName {
public String value();
}
Use it:
public void TC_001(#ParamName("username") String userName, String passWord) { ... }
Access the name:
Parameter parameter = method.getParameters()[0];
ParamName parameterNameAnn = parameter[0].getAnnotation(ParamName.class);
String parameterName;
if (parameterNameAnn != null) {
// get the annotated name
parameterName = parameterNameAnn.value();
} else {
// annotation missing, resort to the "reflected" name
parameterName = parameter.getName();
}
See also
Reflection Tutorial (Oracle)
Especially Parameter Reflection (Oracle)
Compiler options (Oracle)
Annotation Tutorial (Oracle)

C# How to define a variable as global within a (Step Defintion) class

below is an extract from a Step Definition class of my Specflow project.
In the first method public void WhenIExtractTheReferenceNumber() I can successfully extract the text from the application under test, and I have proved this using the Console.WriteLine();
I need to be able to use this text in other methods with in my class I.e. public void WhenIPrintNumber(); But I'm not sure how to do this!
I read about Get/Set but I could not get this working. So I'm thinking is it possible to make my var result global somehow, so that I can call it at anytime during the test?
namespace Application.Tests.StepDefinitions
{
[Binding]
public class AllSharedSteps
{
[When(#"I extract the reference number")]
public void WhenIExtractTheReferenceNumber()
{
Text textCaseReference = ActiveCase.CaseReferenceNumber;
Ranorex.Core.Element elem = textCaseReference;
var result = elem.GetAttributeValue("Text");
Console.WriteLine(result);
}
[When(#"I print number")]
public void WhenIPrintNumber()
{
Keyboard.Press(result);
}
}
}
Thanks in advance for any thoughts.
Here is the solution to my question. Now I can access my variable(s) from any methods within my class. I have also included code that I'm using to split my string and then use the first part of the string. In my case I need the numerical part of '12345 - some text':
namespace Application.Tests.StepDefinitions
{
[Binding]
public class AllSharedSteps
{
private string result;
public Array splitReference;
[When(#"I extract the case reference number")]
public void WhenIExtractTheCaseReferenceNumber()
{
Text textCaseReference = ActiveCase.CaseReferenceNumber;
Ranorex.Core.Element elem = textCaseReference;
result = elem.GetAttributeValue("Text").ToString();
splitReference = result.Split('-'); // example of string to be split '12345 - some text'
Console.WriteLine(splitReference.GetValue(0).ToString().Trim());
}
[When(#"I print number")]
public void WhenIPrintNumber()
{
Keyboard.Press(result); // prints full string
Keyboard.Press(splitReference.GetValue(0).ToString()); // prints first part of string i.e. in this case, a reference number
}
}
}
I hope this help somebody else :)

how to parse non-string values in Opencsv HeaderColumnNameMappingStrategy

I'm using a HeaderColumnNameMappingStrategy to map a csv file with a header into a JavaBean. String values parse fine but any "true" or "false" value in csv doesn't map to JavaBean and I get the following exception from the PropertyDescriptor:
java.lang.IllegalArgumentException: argument type mismatch
The code where it occurs is in CsvToBean, line 64:
protected T processLine(MappingStrategy<T> mapper, String[] line) throws
IllegalAccessException, InvocationTargetException, InstantiationException, IntrospectionException {
T bean = mapper.createBean();
for(int col = 0; col < line.length; col++) {
String value = line[col];
PropertyDescriptor prop = mapper.findDescriptor(col);
if (null != prop) {
Object obj = convertValue(value, prop);
// this is where exception is thrown for a "true" value in csv
prop.getWriteMethod().invoke(bean, new Object[] {obj});
}
}
return bean;
}
protected PropertyEditor getPropertyEditor(PropertyDescriptor desc) throws
InstantiationException, IllegalAccessException {
Class<?> cls = desc.getPropertyEditorClass();
if (null != cls) return (PropertyEditor) cls.newInstance();
return getPropertyEditorValue(desc.getPropertyType());
}
I can confirm (via debugger) that the setter method id correctly retrieved at this point.
The problem occurs in desc.getPropertyEditorClass() since it returns null. I assumed primitive types and its wrappers are supported. Are they not?
I've run into this same issue. The cleanest way is probably to override getPropertyEditor like pritam did above and return a custom PropertyEditor for your particular object. The quick and dirty way would be to override convertValue in anonymous class form, like this:
CsvToBean<MyClass> csvToBean = new CsvToBean<MyClass>(){
#Override
protected Object convertValue(String value, PropertyDescriptor prop) throws InstantiationException,IllegalAccessException {
if (prop.getName().equals("myWhatever")) {
// return an custom object based on the incoming value
return new MyWhatever((String)value);
}
return super.convertValue(value, prop);
}
};
This is working fine for me with OpenCSV 2.3. Good luck!
I resolved this by extending CsvToBean and adding my own PropertyEditors. Turns out opencsv just supports primitive types and no wrappers.
Pritam's answer is great and this is a sample for dealing with datetime format.
PropertyEditorManager.registerEditor(java.util.Date.class, DateEditor.class);
You should write your own editor class like this:
public class DateEditor extends PropertyEditorSupport{
public static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
#Override
public void setAsText(String text){
setValue(sdf.parse(text));}
}