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)
Related
Are there any indicators to deciding whether to use a parameter or member variable?
See below example:
open class BankAccount(val accountCode: String, val accountName: String,
var balance : Double = 0.0) {}
vs.
open class BankAccount(val accountCode: String, val accountName: String) {}
var balance : Double = 0.0
The only question you have to ask is "Is this something that should be set via the constructor?" If yes, then use a parameter. If not, use a property. By adding var you're still making the declaration a property, you're just also adding a shortcut to initialize it from the constructor.
If you're coming from a Java background, looking at the Java equivalent would be helpful. It would be something like this:
public class BankAccount {
private final String mAccountCode;
private final String mAccountName;
private double mBalance;
public BankAccount(String accountCode, String accountName, double balance) {
mAccountCode = accountCode;
mAccountName = accountName;
mBalance = balance;
}
public BankAccount(String accountCode, String accountName) {
this(accountCode, accountName, 0.0d)
}
public void setBalance(double balance) {
mBalance = balance;
}
public double getBalance() {
return mBalance;
}
}
vs.
public class BankAccount {
private final String mAccountCode;
private final String mAccountName;
private double mBalance = 0.0d;
public BankAccount(String accountCode, String accountName) {
mAccountCode = accountCode;
mAccountName = accountName;
}
public void setBalance(double balance) {
mBalance = balance;
}
public double getBalance() {
return mBalance;
}
}
Notice that you get a constructor argument for the balance field in the first case. In either case you can update the value with a method call to the setter.
For your second question, when you should and shouldn't use val or var, the answer is "Use var to make the parameter a writable property, use val to make it a read-only property, and use nothing if you just want constructor args.
Again, the Java equivalent of something like this:
open class Example(var writable : Int, val readable : Int, constructorArg : Int) {
// Could use constructor arg to init another property
private val someOtherProperty : Int = constructorArg
// Or in the init block (the Kotlin "constructor" body)
init {
// Or do something with constructArg in the constructor
}
}
Would be something like this:
public class Example {
private int mWritable;
private final int mReadable;
private final int mSomeOtherProperty;
public Example(int writable, int readable, int contructorArg) {
mWritable = writeable;
mReadable = readable;
// Could use constructor arg to init another property
mSometOtherProperty = constructorArg;
// Or do something with constructArg in the constructor
}
public int getWritable() {
return mWritable;
}
public void setWritable(int writable) {
mWritable = writable;
}
public int getReadable() {
return mReadable;
}
The var attribute makes a property that has both a setter and a getter so you can update it.
The val attribute makes a property that only has a getter so you can read it.
The arg with no keyword makes no property - instead it is passed to the constructor for you to use as needed. This is a trivialized example so it does nothing, but in reality you would use it to either initialize other properties or with an init block.
Again, assuming you're coming from a Java background, you can use Intellij to run view the Kotlin byte code, then convert that to Java to see what the differences in the language do.
Here's the first google hit that explains this:
https://medium.com/#mydogtom/tip-how-to-show-java-equivalent-for-kotlin-code-f7c81d76fa8
Hope that helps!
TLDR: Use a parameter if you need to parameterise.
In the first case, you will be able to start an account with a non-zero balance.
If that is a scenario you find useful, it makes sense to make the balance an (optional) parameter. Otherwise, a member variable is more appropriate.
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
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 :)
Just came across the latest build of Mono.CSharp and love the promise it offers.
Was able to get the following all worked out:
namespace XAct.Spikes.Duo
{
class Program
{
static void Main(string[] args)
{
CompilerSettings compilerSettings = new CompilerSettings();
compilerSettings.LoadDefaultReferences = true;
Report report = new Report(new Mono.CSharp.ConsoleReportPrinter());
Mono.CSharp.Evaluator e;
e= new Evaluator(compilerSettings, report);
//IMPORTANT:This has to be put before you include references to any assemblies
//our you;ll get a stream of errors:
e.Run("using System;");
//IMPORTANT:You have to reference the assemblies your code references...
//...including this one:
e.Run("using XAct.Spikes.Duo;");
//Go crazy -- although that takes time:
//foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
//{
// e.ReferenceAssembly(assembly);
//}
//More appropriate in most cases:
e.ReferenceAssembly((typeof(A).Assembly));
//Exception due to no semicolon
//e.Run("var a = 1+3");
//Doesn't set anything:
//e.Run("a = 1+3;");
//Works:
//e.ReferenceAssembly(typeof(A).Assembly);
e.Run("var a = 1+3;");
e.Run("A x = new A{Name=\"Joe\"};");
var a = e.Evaluate("a;");
var x = e.Evaluate("x;");
//Not extremely useful:
string check = e.GetVars();
//Note that you have to type it:
Console.WriteLine(((A) x).Name);
e = new Evaluator(compilerSettings, report);
var b = e.Evaluate("a;");
}
}
public class A
{
public string Name { get; set; }
}
}
And that was fun...can create a variable in the script's scope, and export the value.
There's just one last thing to figure out... how can I get a value in (eg, a domain entity that I want to apply a Rule script on), without using a static (am thinking of using this in a web app)?
I've seen the use compiled delegates -- but that was for the previous version of Mono.CSharp, and it doesn't seem to work any longer.
Anybody have a suggestion on how to do this with the current version?
Thanks very much.
References:
* Injecting a variable into the Mono.CSharp.Evaluator (runtime compiling a LINQ query from string)
* http://naveensrinivasan.com/tag/mono/
I know it's almost 9 years later, but I think I found a viable solution to inject local variables. It is using a static variable but can still be used by multiple evaluators without collision.
You can use a static Dictionary<string, object> which holds the reference to be injected. Let's say we are doing all this from within our class CsharpConsole:
public class CsharpConsole {
public static Dictionary<string, object> InjectionRepository {get; set; } = new Dictionary<string, object>();
}
The idea is to temporarily place the value in there with a GUID as key so there won't be any conflict between multiple evaluator instances. To inject do this:
public void InjectLocal(string name, object value, string type=null) {
var id = Guid.NewGuid().ToString();
InjectionRepository[id] = value;
type = type ?? value.GetType().FullName;
// note for generic or nested types value.GetType().FullName won't return a compilable type string, so you have to set the type parameter manually
var success = _evaluator.Run($"var {name} = ({type})MyNamespace.CsharpConsole.InjectionRepository[\"{id}\"];");
// clean it up to avoid memory leak
InjectionRepository.Remove(id);
}
Also for accessing local variables there is a workaround using Reflection so you can have a nice [] accessor with get and set:
public object this[string variable]
{
get
{
FieldInfo fieldInfo = typeof(Evaluator).GetField("fields", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfo != null)
{
var fields = fieldInfo.GetValue(_evaluator) as Dictionary<string, Tuple<FieldSpec, FieldInfo>>;
if (fields != null)
{
if (fields.TryGetValue(variable, out var tuple) && tuple != null)
{
var value = tuple.Item2.GetValue(_evaluator);
return value;
}
}
}
return null;
}
set
{
InjectLocal(variable, value);
}
}
Using this trick, you can even inject delegates and functions that your evaluated code can call from within the script. For instance, I inject a print function which my code can call to ouput something to the gui console window:
public delegate void PrintFunc(params object[] o);
public void puts(params object[] o)
{
// call the OnPrint event to redirect the output to gui console
if (OnPrint!=null)
OnPrint(string.Join("", o.Select(x => (x ?? "null").ToString() + "\n").ToArray()));
}
This puts function can now be easily injected like this:
InjectLocal("puts", (PrintFunc)puts, "CsInterpreter2.PrintFunc");
And just be called from within your scripts:
puts(new object[] { "hello", "world!" });
Note, there is also a native function print but it directly writes to STDOUT and redirecting individual output from multiple console windows is not possible.
I have a scenario where i need to use the payload as
{"authType":"PDS"}
or
{"authType":"xyz","authType2":"abc",}
or
{"authType":"xyz","authType2":"abc","authType3":"123"}
or
any combination except for null values.
referring to the code i have 3 fields but only not null value fields be used.
Basically i don't want to include the field which has null value.
Are there any annotations to be used to get it done
public class AuthJSONRequest {
private String authType;
private String authType2;
private String authType3;
public String getAuthType() {
return authType;
}
public void setAuthType(String authType) {
this.authType = authType;
}
public String getAuthType2() {
return authType2;
}
public void setAuthType2(String authType2) {
this.authType2 = authType2;
}
public String getAuthType3() {
return authType3;
}
public void setAuthType3(String authType3) {
this.authType3 = authType3;
}
}
Try JSON Views? See this or this. Or for more filtering features, see this blog entry (Json Filters for example).
This is exactly what the annotation #JsonInclude in Jackson2 and #JsonSerialize in Jackson are meant for.
If you want a property to show up only when it is not equal to null, add #JsonInclude(Include.NON_NULL) resp. #JsonSerialize(include=Include.NON_NULL).