using Telerik testing environment - c#

I am learning how to use the Telerik test environment.
I created a test that runs through my program. One of the steps is to create a repository, into which I will upload data. I would like to run this test numerous times as a load test, so the name needs to be dynamic. I would like to create a name such as "Repository_Date_Time, since no matter how many times I use it, uniqueness is guaranteed.
I created a code step right before the text box insertion step. I would like to generate a string, and then use it in the next step so that the repository is created with a unique name.
Code generated is: this is in the steps within the telerik application
[WebTest_CodedStep] : New Coded Step
Then, within this step, I can hard code stuff:
[CodedStep(#"New Coded Step")]
public void WebTest_CodedStep()
{
}
I want to use something like this: string currentTime = DateTime.Now.ToString("HH:mm:ss");
and then use the saveNow contained data as an ending to a string to make it unique, but it must be done within the following step:
Type 'Moshe-Master Repository Test01' into Item0Textboxchanged
TypedText: Moshe-Master Repository Test01
So that the red name will be substituted by a variable carrying the new string which I creatred.
The TypedText box is the value being typed automatically, and I would like to change it with the generated value from the previous step. Can a TypedText value be dynamic?
Thanks!
EDIT: I just realized that therre is a way to use a variable as input, however, I do not know where I can create it. The location where I can put it as input is in the top right state-chart with all current data being used for that particular step. (bindings) is set to collection at the moment. When I try to change it into a variable it tells me that the variable needs to be created- it does not specify where.

Related

What's the easiest way to create a managed visualiser in C#?

I have a background in C++ and recently I started working in C#.
I have written following pieces of code (in Visual Studio):
var list_Loads = database.GetData<Load>().ToList();
var test_list = list_Loads.Where(o => (o.Name.Substring(0, 3) == "123")).ToList();
When I run the program and I move my mouse over both lists, first I get the count, which is very useful, but when I ask for the entries, this is what I get:
0 : namespace.Load
1 : namespace.Load
2 : namespace.Load
...
Not very useful, as you can imagine :-)
So my question: how can I show the Name attributes of those objects?
I thought: no problem. I have a background in native visualisers, so it should be rather easy to turn this into useful information, but then it comes:
In order to alter the way that those objects are represented, there is the first proposal to add a [DebuggerDisplay] "tag" to the definition of that class in source code.
However, as those classes are part of a framework I'm just referring to, I don't have access to the source code and hence I can't modify this.
Then I found another solution, which comes down to: "Write an entire C# project, debug, test and install it and it might work" (see documentation on "Custom visualisers of data" on the Microsoft website).
I almost choked in my coffee: writing an entire project, just for altering the view of an object??? (While, in C++, you just create a simple .natvis file, mention the classname and some configuration, launch .nvload and that's it.
Does anybody know a simple way to alter the appearance of C# object, without needing to pass through the whole burden of creating an entire C# project?
By the way, when I try to load a natvis file in Visual Studio immediate window, this is what I get:
.nvload "C:\Temp_Folder\test.natvis"
error CS1525: Invalid expression term '.'
What am I doing wrong?
Thanks in advance
OP (my emphasis):
In order to alter the way that those objects are represented, there is the first proposal to add a [DebuggerDisplay] "tag" to the definition of that class in source code.
However, as those classes are part of a framework I'm just referring to, I don't have access to the source code and hence I can't modify this.
Does anybody know a simple way to alter the appearance of C# object, without needing to pass through the whole burden of creating an entire C# project?
If you just want to specify [DebuggerDisplay] on a type, you don't have to have access to the source code. You can make use of [assembly:DebuggerDisplay()] and control how a type appears in the debugger. The only downside is that [assembly:DebuggerDisplay()] naturally only affects the current assembly whose code your mouse is hovering over. If you wish to use the customised display in other assemblies that you own, then you must repeat the [assembly:DebuggerDisplay()] definition.
Here's an easy before-and-after example with DateTime. I picked DateTime because we generally don't have access to the source code and it has some interesting properties:
var items = new List<DateTime>
{
DateTime.Now.AddDays(-2),
DateTime.Now.AddDays(-1),
DateTime.Now
};
...which on my machine defaults to:
Maybe I'm fussy and I just want to see:
Day of the week and
Day of the year
...I can do that via:
using System.Diagnostics;
[assembly: DebuggerDisplay("{DayOfWeek} {DayOfYear}", Target = typeof(DateTime))]
...which results in:
Example:
namespace DebuggerDisplayTests
{
public class DebuggerDisplayTests
{
public DebuggerDisplayTests()
{
var items = new List<DateTime>
{
DateTime.Now.AddDays(-2),
DateTime.Now.AddDays(-1),
DateTime.Now
};
}
}
.
.
.
}
Overrides
[assembly:DebuggerDisplay()] can also be used as a means to override pre-existing [DebuggerDisplay] on a 3-rd party type. Don't like what style they have chosen? Is the type showing far too much information? Change it with [assembly:DebuggerDisplay()].

Is there a way to set Allure attributes dynamically?

In my testing scenario, I've set up a few parameterized tests in order to test various data inputs to a function. I'm also using Allure to generate my test report. My issue is that if I set Allure attributes for things like suite and sub suite for instance in the test class itself, it shows the same static data for every test entry in the report. What I'd like to do is to have the sub suite attribute read something like "Test data for input " and then either input 1, 2, 3, etc., depending on which input is being ran through at the time. The input object does contain an index number property, so getting the specific input number isn't an issue, I just need a way to write that to the Allure attribute.
The C# based allure implementation I'm using does have an AllureLifecycle class, which has in instance property (Which from what I understand should give access to the currently running test instance), and then a UpdateTestCase method. What I'm not sure of though is whether the suite and attributes like it can even be updated using this method, or if they are required to be set via data annotations.
What I guess I'm trying to figure out is if what I want to do is even possible? Am I on the right track here?

Epicor 10 How to store data between BPM pre and post processing?

I'm tying to migrate an Epicor V9 system with Progress/ABL code to v10 with C# code. I've got most of it done but I need a way to keep data between a BPMs pre and post processing. The comments in the original ABL code state:
Description : This function stores data from a BPM pre processing action, it does this by using a private-data (storage attribute) on the calling program...
this remains in scope during both the BPM pre and BPM post forward to procedure calls
The Epicor v9 system was set up such that the Quote form calls the BPM pre/post processing in a .p file. The .p file in turned call the code I am trying to migrate in a .i file. It looks to be a simple stack or array of strings.
What would be used in Epicor 10 to persist data between pre/post BPM processing like the .i code did in V9?
You can use CallContext.Properties for this.
In E10.0 the CallContext.Properties was of type Epicor.Utilities.PropertyBag, and items would be accessed as below:
//Add
CallContext.Properties.Add("LineRef", LineRef);
// Get
var LineRef = (string)CallContext.Properties["LineRef"];
// Remove
CallContext.Properties.Remove("LineRef");
E10.1 CallContext.Properties is now of type System.Collections.Concurrent.ConcurentDictionary, which is a .Net built in type and much better documented. However the methods to add and remove entries from it have changes as below:
//Add
bool added = CallContext.Properties.TryAdd("LineRef", LineRef);
// Get
var LineRef = (string)CallContext.Properties["LineRef"]; //Note: Do not use .ToString() this converts instead of unboxing.
// Remove
object dummy;
bool foundAndRemoved = CallContext.Properties.TryRemove("LineRef", out dummy);
To use this your class needs to inherit from ContextBoundBase and implement the only the context bound constructor or you will get 'Ice.ContextBoundBase<Erp.ErpContext>.ContextBoundBase()' is obsolete: 'Use the constructor that takes a data context'
public partial class MyInvokeExternalMethodThing : ContextBoundBase<ErpContext>
{
public MyInvokeExternalMethodThing(ErpContext ctx) : base(ctx)
{
}
In E10.1 you can put any kind of object into this, so if you have an array of strings you don't need to use the old trick of tilde~separated~values.
I don't know about using .i files from E9 but I do know how to persist data between pre and post method directives in E10. Hopefully this helps.
There are a couple of different ways to do this. If when creating the pre-process bpm you chose the "Execute Custom Code" option. You can do it directly in your code using callContextBpmData. Almost all of the field names are similar to that of the user fields that E9 used (i.e. Number01, Chracter01, Date01).
In your code if you are setting text you could simply type:
callContextBpmData.Character01 = "some text";
Alternatively you could set it directly in the bpm designer without any code. In the designer left window pane, scroll all the way to the bottom, you should see something called "Set BPM Data Field". Drag it into the design area. After dragging it into the designer area you should see the option to set a field and its value in the bottom window pane. Select the field, then when you select "value" you are taken to a window similar to baq calculated field designer. You can use static data or use the data in the business object to calculate a value.

C# Dynamic List Class

I have a bit of a weird issue. Working in C# script with SSIS I have developed a need to build a List based off Dynamic Data.
Background
To explain it, a script task is fired that has a variable API URL, this goes off and pulls a JSON string back and then throws it into a strongly typed list using the following code.
var listobject = get_APIData<ApplicationOneDataSet>(url)
The class that does this is long winded and not really needed in the context of this issue.
ApplicationOneDataSet is a strongly typed match to one of the possible JSON results returned by get_APIData.
Now I have a need to change ApplicationOneDataSet to ApplicationTwoDataSet dynamically based on which API URL I pass to the script.
So what I have done is send through a second variable to the script called class name which contains the string "ApplicationDataSetOne" or "ApplicationDataSetTwo" based on which context I call it under.
The Question
My question is how can I dynamically vary this line:
var listobject = get_APIData<ApplicationOneDataSet>(url)
With the string variable passed into the script.
My original thinking was something along the lines of this:
var ClassType = (string) Dts.Variables["AppClassName"].Value;
Type type = Type.GetType(ClassType);
var listobject = get_APIData<type>(url)
Though it doesn't seem to like that. Any tips would be great!
As long as there is exactly two types you can use and you know them at compile time, I would not look further than a simple if. It works, it's easy, everyone understands it.
You can do it totally dynamic at runtime, but that's a huge pain in the... where you don't want it to be. If you really want to go down that rabbit hole, you can find more information here.
I'm not sure I fully understood what you are trying to do, but how about writing an interface ApplicationDataSet and then making a list of it? This way your list is going to be able to contain both types of data.

Setting up SpecFlow to pass in identifiers

I am new to C# and am trying to use SpecFlow as I used to use Gherkin by giving a unique name to an item and then passing in the name in the Step Definition. My question is about how to add in the identifier when I create an object so I can call the object without having to pass in the actual name of the object every time that I create a step.
So, for instance the code would look something like this:
[When(#"I click the (.*) button")]
public void ClickTheButton(string ButtonName)
{
driver.Click(ButtonName)
//ButtonName would be a string that would call to the ID for the ADD button
}
I want to be able to put in something like "Add" (so the line would read "When I click the ADD button") and then have the code search for the "ADD" identifier.
I know that this is possible in Ruby/Cucumber by using a DOM and then passing in XML with gherkin names. In Ruby/Cucumber the object would look something like this:
<button gherkin_name="ADD" key="id" value="add_button_12685"/>
However, I am finding absolutely no way of doing that in C# with SpecFlow and this is something that I really need to be able to do.
Is there a way to do this at all? All I'm really trying to do is link a handle/parameter name that business users could actually use to a Page Object like you can in Ruby/Cucumber without making the user know the code in the background. And, incidentally, the names of the objects are almost exactly like the gherkin line that I added in, thus they are very weird to have a user write. This is the reason that I'd like to have just an identifier for the user.
Thanks in advance for your help.
EDIT: I realise now I was not clear enough in my original post so perhaps some background will help. I am using Selenium-Webdriver to test a website that has hundreds of items on it. Writing a different step for every single item on every single page would be exceedingly tedious and time consuming. Because there are many of the exact same items with the exact same characteristics (for instance there are something like 50 buttons that all behave similarly on a single page and the site is dozens of pages) on the pages, writing a single method for testing them seems the most logical idea. Identifying these items with an identifier that the business could use would cut down on bulk inside of the Steps, the number of steps written, and the likelihood that the business users would feel comfortable using the code which is the end goal.
You can do what you want if you are using the PageObject pattern and have a property Buttons (probably on a base PageObject class) which exposes the available buttons as a collection (which can be done via reflection) and then you can just do something like:
[When(#"I click the (.*) button")]
public void ClickTheButton(string ButtonName)
{
myPage.Buttons.First(button=>button.Name==ButtonName).Click;
}
but I would take what AutomatedChaos said into consideration and not use this in a step in the gerkin but just have this as a helper method something like this
[When(#"I add a widget")]
public void AddAWidget(string ButtonName)
{
ClickTheButton("Add")
}
private void ClickTheButton(string ButtonName)
{
myPage.Buttons.First(button=>button.Name==ButtonName).Click;
}
your Buttons property doesn't have to be done with reflection, the simplest implementation is something like this:
public IEnumerable<IWebElement> Buttons
{
yield return AddButton;
yield return RemoveButton;
yield return SomeOtherButton;
//etc etc
}
but using reflection will mean that as you add buttons to the page object you don't need to remember to add them to this method, they will be found automatically.
SpecFlow is only the BDD framework. It will not drive browsers itself, you need to install additional packages that drives the browser.
With C#, you have a few options:
Selenium, the best known and works with the Page Object you are accustomed with.
Fluent Automation, an upcoming library that works as a wrapper on top of Selenium, and makes the interfacing easier (more natural language)
CodedUI, Microsofts web and UI test solution that comes natively with Visual Studio Test edition.
On a personal note, I consider Selenium (with or without Fluent Automation) the best fitted to work with SpecFlow (comparisson)
If you want to install Selenium or other packages, you can install the NuGet package manager to easily search, install and update packages for you.
Lastly, have you considered to use more domain specific Gherkin phrases like When I add a Wabberjock instead of When I press the Add button? This is where the power of BDD lies: Exposing the intention while hiding the implementation details.

Categories