How to use generated code with a parameter of RepoItemInfo? - ranorex

We use the Ranorex Studio in our company for black-box testing. I am a newbie concerning black-box testing. For a very first automated test, I want to create two tests that use a number of methods from a file that was generated by adding a recording module and changing this to user code by clicking the items, pressing the right mouse button and selecting 'Convert to user code'.
The code has methods (where the names were refactored by me) of the form public void Mouse_Click_<something>(RepoItemInfo inputtagInfo, …). This means that whenever I want to call any such method, I should pass a RepoItemInfo object. How can I define the "proper" object to call this method? In other words: What to write on the right-hand side of info = ????????
According to the Ranorex help page, using RepoItemInfo
as arguments for user code actions enables a variety of possibilities
such as providing a framework of smart test actions, defining generic
technology independent get/set value actions, combining several
related actions to one user code action, implementing complex
validations and many more.
I have the following code:
namespace FirstTestProject
{
public partial class OpenIVMAndJobsite
{
private GoSearchJobsite gsj;
private RepoItemInfo info;
/// <summary>
/// This method gets called right after the recording has been started.
/// It can be used to execute recording specific initialization code.
/// </summary>
private void Init()
{
// Your recording-specific initialization code goes here.
gsj = new GoSearchJobsite();
info = ???????;
}
public void JobsiteSearch()
{
gsj.Mouse_Click_Country(info, Properties.EAustrianCountries.Wien);
}
public void Mouse_Click()
{
Report.Log(ReportLevel.Info, "Mouse", "Mouse Left Click at {X=0,Y=0}.");
Mouse.MoveTo(0, 0);
Mouse.Click(System.Windows.Forms.MouseButtons.Left);
}
}
[…]
public partial class GoAndSearchInJobsite
{
/// <summary>
/// This method gets called right after the recording has been started.
/// It can be used to execute recording specific initialization code.
/// </summary>
private void Init()
{
// Your recording specific initialization code goes here.
}
public void Mouse_Click_Country(RepoItemInfo atagInfo, string country)
{
Report.Log(ReportLevel.Info, "Mouse", "<" + country + ">\r\nMouse Left Click item 'atagInfo' at 16;8.", atagInfo);
atagInfo.FindAdapter<ATag>().Click("16;8");
}
[…]
}
/// <summary>
/// Description of Properties.
/// </summary>
public static class Properties
{
public enum EAustrianCountries
{
Alle,
Burgenland,
Kärnten,
Niederösterreich,
Oberösterreich,
Salzburg,
Steiermark,
Tirol,
Vorarlberg,
Wien
}
}
}

Each item in the repository will have a corresponding ReportItemInfo object as well.
For example, if you have a button as ButtonOK, you will also find ButtonOKInfo object. You can use it with repo.<window>.control mechanism.
If you are dealing with window itself, the object will be repo.<window>.selfInfo.
Hope it helps.
Thanks,
Manoj

Related

How are domain events dispatched from within domain objects?

Domain objects shouldn't have any dependencies, hence no dependency injection either. However, when dispatching domain events from within domain objects, I'll likely want to use a centralised EventDispatcher. How could I get hold of one?
I do not want to return a list of events to the caller, as I'd like them to remain opaque and guarantee their dispatch. Those events should only be consumed by other domain objects and services that need to enforce an eventual consistent constraint.
See Udi Dahan's domain events
Basically, you register one or more handlers for your domain events, then raise an event like this:
public class Customer
{
public void DoSomething()
{
DomainEvents.Raise(new CustomerBecamePreferred() { Customer = this });
}
}
And all the registered handler will be executed:
public void DoSomethingShouldMakeCustomerPreferred()
{
var c = new Customer();
Customer preferred = null;
DomainEvents.Register<CustomerBecamePreferred>(p => preferred = p.Customer);
c.DoSomething();
Assert(preferred == c && c.IsPreferred);
}
This is basically implementing Hollywood Principle (Don't call us, we will call you), as you don't call the event handler directly - instead the event handler(s) get executed when the event is raised.
I'll likely want to use a centralised EventDispatcher. How could I get hold of one?
Pass it in as an argument.
It probably won't look like an EventDispatcher, but instead like some Domain Service that describes the required capability in domain specific terms. When composing the application, you choose which implementation of the service to use.
You are asking to have it both ways. You either need to inject the dependency or invert control and let another object manager the interaction between Aggregate and EventDispatcher. I recommend keeping your Aggregates as simple as possible so that they are free of dependencies and remain testable as well.
The following code sample is very simple and would not be what you put into production, but illustrates how to design Aggregates free of dependencies without passing around a list of events outside of a context that needs them.
If your Aggregate has a list of events within it:
class MyAggregate
{
private List<IEvent> events = new List<IEvent>();
// ... Constructor and event sourcing?
public IEnumerable<IEvent> Events => events;
public string Name { get; private set; }
public void ChangeName(string name)
{
if (Name != name)
{
events.Add(new NameChanged(name);
}
}
}
Then you might have a handler that looks like:
public class MyHandler
{
private Repository repository;
// ... Constructor and dependency injection
public void Handle(object id, ChangeName cmd)
{
var agg = repository.Load(id);
agg.ChangeName(cmd.Name);
repository.Save(agg);
}
}
And a repository that looks like:
class Repository
{
private EventDispatcher dispatcher;
// ... Constructor and dependency injection
public void Save(MyAggregate agg)
{
foreach (var e in agg.Events)
{
dispatcher.Dispatch(e);
}
}
}

Resolve Service Implementation from Autofac based on Runtime Session Value

Need some help trying to solve a problem resolving an implementation of a service at runtime based on a parameter. In other words use a factory pattern with DI.
We have Autofac wired in to our MVC application. I am trying to figure out how we can use a user session variable (Call it Ordering Type) to be used for the Dependency Resolver to resolve the correct implementation of a service.
An example of what we are trying to do.
The application has two "types" of ordering - real eCommerce type of ordering (add stuff to a shopping cart, checkout etc).
The other is called Forecast ordering. Users create orders - but they do not get fulfilled right away. They go through an approval process and then fulfilled.
The bottom line is the data schema and back end systems the application talks to changes based on the order type.
What I want to do is:
I have IOrderManagerService
public interface IOrderManagerService
{
Order GetOrder(int orderNumber);
int CreateOrder(Order order);
}
Because we have two ordering "types" - I have two implementations of the the IOrderManagerService:
public class ShelfOrderManager : IOrderManagerService
{
public Order GetOrder(int orderMumber)
{
...code
}
public int CreateOrder(Order order)
{
...code
}
}
and
public class ForecastOrderManager: IOrderManagerService
{
public Order GetOrder(int orderMumber)
{
...code
}
public int CreateOrder(Order order)
{
...code
}
}
My First question is - in my MVC application - do I register these implementations as?
builder.RegisterType<ShelfOrderManager>().As<IOrderManagerService>();
builder.RegisterType<ForecastOrderManager>().As<IOrderManagerService>();
What we are planning on doing is sticking the user selected ordering type in a users session. When a user wants to view order status - depending on their selected ordering "type" - I need the resolver to give the controller the correct implementation.
public class OrderStatusController : Controller
{
private readonly IOrderManagerService _orderManagerService;
public OrderStatusController(IOrderManagerService orderManagerService)
{
//This needs to be the correct implementation based on the users "type".
_orderManagerService = orderManagerService;
}
public ActionResult GetOrder(int orderNumber)
{
var model = _orderManagerService.GetOrder(orderNumber);
return View(model);
}
}
I've ready about the the delegate factory and this answer explains the concept well.
The problem is the runtime parameters are being used to construct the service and resolve at runtime. i.e.
var service = resolvedServiceClass.Factory("runtime parameter")
All this would do is give me "service" that used the "runtime parameter" in the constructor.
I've looked at Keyed or Named resolution too.
At first I thought I could combine these two techniques - but the controller has the dependency on the interface - not the concrete implementation. (as it should)
Any ideas on how to get around this would be MUCH appreciated.
As it would turn out we were close. #Andrei is on target with what we did. I'll explain the answer below for the next person that comes across this issue.
To recap the problem - I needed to resolve a specific concrete implementation of an interface using Autofac at run time. This is commonly solved by the Factory Pattern - but we already had DI implemented.
The solution was using both. Using the delegate factory Autofac supports, I created a simple factory class.
I elected to resolve the component context privately
DependencyResolver.Current.GetService<IComponentContext>();
versus having Autofac resolve it predominately so I did not have to include IComponentContext in all of my constructors that that will be using the factory.
The factory will be used to resolve the services that are dependent on run time parameters - which means wherever a
ISomeServiceThatHasMultipleImplementations
is used in a constructor - I am going to replace it with ServiceFactory.Factory factory. I did not want to ALSO include IComponentContext wherever I needed the factory.
enum OrderType
{
Shelf,
Forecast
}
public class ServiceFactory : IServiceFactory
{
private readonly IComponentContext _componentContext;
private readonly OrderType _orderType;
public ServiceFactory(OrderType orderingType)
{
_componentContext = DependencyResolver.Current.GetService<IComponentContext>();
_orderType = orderingType;
}
public delegate ServiceFactory Factory(OrderType orderingType);
public T Resolve<T>()
{
if(!_componentContext.IsRegistered<T>())
return _componentContext.ResolveNamed<T>(_orderType.ToString());
return _componentContext.Resolve<T>();
}
}
With the factory written, we also used the Keyed services.
Using my order context -
public interface IOrderManagerService
{
Order GetOrder(int orderNumber);
int CreateOrder(Order order);
}
public class ShelfOrderManager : IOrderManagerService
{
public Order GetOrder(int orderNumber)
{
...
}
public int CreateOrder(Order order)
{
...
}
}
public class ForecastOrderManager : IOrderManagerService
{
public Order GetOrder(int orderNumber)
{
...
}
public int CreateOrder(Order order)
{
...
}
}
The registration of Keyed services:
//register the shelf implementation
builder.RegisterType<ShelfOrderManager>()
.Keyed(OrderType.Shelf)
.As<IOrderManager>();
//register the forecast implementation
builder.RegisterType<ForecastOrderManager>()
.Keyed(OrderType.Shelf)
.As<IOrderManager>();
Register the factory:
builder.RegisterType<IMS.POS.Services.Factory.ServiceFactory>()
.AsSelf()
.SingleInstance();
Finally using it in the controllers (or any other class for that matter):
public class HomeController : BaseController
{
private readonly IContentManagerService _contentManagerService;
private readonly IViewModelService _viewModelService;
private readonly IApplicationSettingService _applicationSettingService;
private readonly IOrderManagerService _orderManagerService;
private readonly IServiceFactory _factory;
public HomeController(ServiceFactory.Factory factory,
IViewModelService viewModelService,
IContentManagerService contentManagerService,
IApplicationSettingService applicationSettingService)
{
//first assign the factory
//We keep the users Ordering Type in session - if the value is not set - default to Shelf ordering
_factory = factory(UIUserSession?.OrderingMode ?? OrderType.Shelf);
//now that I have a factory to get the implementation I need
_orderManagerService = _factory.Resolve<IOrderManagerService>();
//The rest of these are resolved by Autofac
_contentManagerService = contentManagerService;
_viewModelService = viewModelService;
_applicationSettingService = applicationSettingService;
}
}
I want to work out a bit more handling of the Resolve method - but for the first pass this works. A little bit Factory Pattern (where we need it) but still using Autofac to do most of the work.
I would not rely on Autofac for this. IOC is used to resolve a dependency and provide an implementation for it, what you need is to call a different implementation of the same interface based on a decision flag.
I would use a simple factory basically, like a class with 2 static methods and call whichever implementation you need need to when you know what the decision is. This gives you the run-time resolver you are after. Keep it simple I'd say.
This being said it seems there is another option. Have a look at the "select by context" option, maybe you can redesign your classes to take advantage of this: http://docs.autofac.org/en/latest/faq/select-by-context.html

How do you add a runtime string parameter into a dependency resolution chain?

How could I setup my chosen DI for this kind of setup:
public abstract class BaseRepo
{
public BaseRepo(string token)
{
}
}
public RepoA : BaseRepo, IRepoA
{
// implementation of interface here
}
public ViewModelA
{
IRepoA _repo;
public ViewModelA(IRepoA repo)
{
this._repo = repo;
}
public DoMethod()
{
this._repo.DoSomeStuff();
}
}
In real scenario, the token parameter on the base class is resolved after the user has been logged in. I was thinking of just configuring the interfaces for DI after the login but I'm not sure if that a right thing do.
I looked at some Factories but I can't make it to work.
My choice of DI probably goes to AutoFac/Ninject and the project is Xamarin mobile app
In real scenario, the token parameter on the base class is resolved
after the user has been logged in.
This means that the token parameter is runtime data. Prevent injecting runtime data into your components. Your components should be stateless. Instead, runtime data should be passed on through method calls through the previously constructed object graph of components. Failing to do so, will make it much more complicated to configure and verify your object graphs.
There are typically to ways of passing runtime data. Either you pass it on through method calls from method to method through the object graph, or your components call a method that returns that correct value. This token seems like it is contextual information and that would typically mean you choose the latter option:
public interface ITokenProvider {
string GetCurrentToken();
}
// Don't use base classes: base classes are a design smell!
public RepoA : IRepoA
{
private readonly ITokenProvider tokenProvider;
public RepoA(ITokenProvider tokenProvider) {
this.tokenProvider = tokenProvider;
}
// IRepoA methods
public A GetById(Guid id) {
// Get token at runtime
string token = this.tokenProvider.GetCurrentToken();
// Use token here.
}
}
In your Composition Root, you will have to create an implementation for this ITokenProvider. How this implementation looks is highly dependent on how you wish to store this token, but here's a possible implementation:
public sealed class AspNetSessionTokenProvider : ITokenProvider {
public string GetCurrentToken() {
return (string)HttpContext.Current.Session["token"];
}
}

Dart: how to reference methods of classes

While writing library documentation I need to be able to reference (i.e. link to) methods from other classes (in the same library) but with the same method name (i.e. reference the delegating method from the docs of the one that is doing the work).
I have tried ClassName.method (does not work) and directly using the method (references the same class method).
Any ideas?
Thanks.
/// [B.someMethod] ..
/// [someMethod] ..
class A {
void someMethod() {
}
}
/// [A.someMethod]
/// [someMethod]
class B {
void someMethod() {
}
}
/// [A.someMethod]
void main() {
new A().someMethod();
}
All references in the doc comments work for me in this example, but sometimes DartEditor shows them only as links after a delay or after some other edits.
Its a docgen issue/bug - can be monitored here: https://code.google.com/p/dart/issues/detail?id=22144

Global [BeforeScenario], [AfterScenario] steps in SpecFlow

We're trying to implement global hooks on our specflow tests and are not entirely sure how [BeforeScenario] and [AfterScenario] attributed methods work.
The way I've seen it done, those attributes are always defined in a class containing specific steps used in a few scenarios.
Can they go somewhere so they apply to all scenarios? Or does attributing the methods with [BeforeScenario] and [AfterScenario] cause them to be run for all scenarios, regardless of where they're actually placed?
Hmm... From what I knew and according to the documentation these hooks are always global, i.e. from http://www.specflow.org/documentation/hooks/
Hooks
The hooks (event bindings) can be used to perform additional automation logic on specific events, like before the execution of a scenario.
The hooks are global but can be restricted to run only for features or scenarios with a specific tag (see below). The execution order of hooks for the same event is undefined.
In fact by producing a small demo project with the following
[Binding]
public class Unrelated
{
[BeforeScenario]
public void WillBeCalledIfGlobal()
{
Console.WriteLine("I'm global");
}
}
[Binding]
public class JustTheTest
{
[Given("nothing")]
public void GivenNothing()
{
// Don't do anything
}
}
Then the test specification of
As a developer
In order to understand how BeforeSpecifcation works
I want to know what the following does
Scenario: See if BeforeSpecifcation hook gets called
Given nothing
The get the output
I'm global
Given nothing
-> done: JustTheTest.GivenNothing() (0.0s)
So it really does look as if the documentation is correct, and you should use tagging to control if the BeforeScenario \ AfterScenario are run before or after your scenario.
There is also a good example of how tagging works here -> Feature-scoped step definitions with SpecFlow?
Yes, you can create global BeforeScenario and AfterScenario methods, but in practice I find that this is not desirable, as usually the same before and after steps do not apply to all steps in a test project.
Instead I create a base class for my step definitions, which would have the BeforeScenario and AfterScenarios methods I'd like applied to all of my scenarios e.g.
public class BaseStepDefinitions
{
[BeforeScenario]
public void BeforeScenario()
{
// BeforeScenario code
}
[AfterScenario]
public void AfterScenario()
{
// AfterScenario code
}
}
Note that I have not used the Binding attribute on this class. If you do include it then the BeforeScenario and AfterScenario steps would be global.
I then derive my step definion classes from this base step definition class, so that they will have the Before and After scenario methods e.g.
[Binding]
public class SpecFlowFeature1Steps : BaseStepDefinitions
{
[Given(#"I have entered (.*) into the calculator")]
public void GivenIHaveEnteredIntoTheCalculator(int inputValue)
{
ScenarioContext.Current.Pending();
}
[When(#"I press add")]
public void WhenIPressAdd()
{
ScenarioContext.Current.Pending();
}
[Then(#"the result should be (.*) on the screen")]
public void ThenTheResultShouldBeOnTheScreen(int expectedResult)
{
ScenarioContext.Current.Pending();
}
}
Whilst this approach is not global, by making all StepDefinitions derive from a BaseStepDefinition class we achieve the same outcome.
It also gives more control i.e. if you don't want the BeforeScenario or AfterScenario binding then don't derive from the base steps.
Sorry this doesn't work. As soon as you start using multiple Binding classes you end up with multiple calls. For example if I extend the example above to split the bindings into three classes,
[Binding]
public class SpecFlowFeature1Steps : BaseStepDefinitions
{
[Given(#"I have entered (.*) into the calculator")]
public void GivenIHaveEnteredIntoTheCalculator(int inputValue)
{
//ScenarioContext.Current.Pending();
}
}
[Binding]
public class SpecFlowFeature2Steps : BaseStepDefinitions
{
[When(#"I press add")]
public void WhenIPressAdd()
{
//ScenarioContext.Current.Pending();
}
}
[Binding]
public class SpecFlowFeature3Steps : BaseStepDefinitions
{
[Then(#"the result should be (.*) on the screen")]
public void ThenTheResultShouldBeOnTheScreen(int expectedResult)
{
//ScenarioContext.Current.Pending();
}
}
public class BaseStepDefinitions
{
[BeforeScenario]
public void BeforeScenario()
{
// BeforeScenario code
Console.WriteLine("Before. [Called from "+ this.GetType().Name+"]");
}
[AfterScenario]
public void AfterScenario()
{
// AfterScenario code
Console.WriteLine("After. [Called from " + this.GetType().Name + "]");
}
}
Then when I run it, the output is
Before. [Called from SpecFlowFeature1Steps]
Before. [Called from SpecFlowFeature2Steps]
Before. [Called from SpecFlowFeature3Steps]
Given I have entered 50 into the calculator
-> done: SpecFlowFeature1Steps.GivenIHaveEnteredIntoTheCalculator(50) (0.0s)
And I have entered 70 into the calculator
-> done: SpecFlowFeature1Steps.GivenIHaveEnteredIntoTheCalculator(70) (0.0s)
When I press add
-> done: SpecFlowFeature2Steps.WhenIPressAdd() (0.0s)
Then the result should be 120 on the screen
-> done: SpecFlowFeature3Steps.ThenTheResultShouldBeOnTheScreen(120) (0.0s)
After. [Called from SpecFlowFeature1Steps]
After. [Called from SpecFlowFeature2Steps]
After. [Called from SpecFlowFeature3Steps]
What you can do, in order to control the 'BeforeScenario' and 'AfterScenario' is use tags. This gives you the control of which Scenario's should run which before and after block. Your scenario would look like this:
#GoogleChrome
Scenario: Clicking on a button
Given the user is on some page
When the user clicks a button
Then something should happen
Here you could let the 'BeforeScenario' start a browser session in Google Chrome for you, and implement similar tags for different browsers. Your 'BeforeScenario' would look like this:
[Binding]
class Browser
{
[BeforeScenario("GoogleChrome")]
public static void BeforeChromeScenario()
{
// Start Browser session and do stuff
}
[AfterScenario("GoogleChrome")]
public static void AfterChromeScenario()
{
// Close the scenario properly
}
I think using tags is a nice way of keeping your scenario's clean and give you the extra functionality to let you control what each scenario should do.

Resources