Giter VIP home page Giter VIP logo

specflow.assist.dynamic's Introduction

SpecFlow.Assist.Dynamic

SpecFlow.Assist.Dynamic is a couple of simple extension methods for the SpecFlow Table object that helps you to write less code.

What would you rather write? This:

[Binding]
public class StepsUsingStaticType
{
    private Person _person;

    [Given(@"I create an instance from this table")]
    public void GivenICreateAnInstanceFromThisTable(Table table)
    {
        _person = table.CreateInstance<Person>();
    }

    [Then(@"the Name property on Person should equal '(.*)'")]
    public void PersonNameShouldBe(string expectedValue)
    {
        Assert.AreEqual(expectedValue, _person.Name);
    }
}

// And then make sure to not forget defining a separate Person class for testing, 
// since you don't want to reuse the one your system under test is using - that's bad practice

// Should probably be in another file too...
// might need unit tests if the logic is complicated
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public DateTime BirthDate { get; set; }
    public double LengthInMeters { get; set; }
}

Or this:

[Binding]
public class StepsUsingDynamic
{
    private dynamic _instance;

    [Given(@"I create an instance from this table")]
    public void c(dynamic instance) { _instance = instance; }

    [Then(@"the Name property should equal '(.*)'")]
    public void NameShouldBe(string expectedValue) { Assert.AreEqual(expectedValue, _instance.Name);  }
}

The later version uses SpecFlow.Assist.Dynamic. Shorter, sweater and more fun!

well, this is may be one of the best usecase for dynamic i have ever seen

A happy SpecFlow.Assists.Dynamic user

Full documentation on the wiki

specflow.assist.dynamic's People

Contributors

kntajus avatar marcusoftnet avatar romerod avatar srkl avatar tjdekker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

specflow.assist.dynamic's Issues

CreateDynamicInstance from a table with a single Field and Value doesn't create the ExpandoObject as expected

Calling CreateDynamicInstance for a table with a single Field and Value row doesn't create the ExpandoObject as expected.

To reproduce, add the following scenario in .\Specs\DynamicInstancesFromTable.feature:

Scenario: Create dynamic instance from table with a single Field and Value
	When I create a dynamic instance from this table
		| Field            | Value      |
		| Name             | Marcus     |
	Then the Name property should equal 'Marcus'

Result:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : 'System.Dynamic.ExpandoObject' does not contain a definition for 'Name'

Instead of the ExpandoObject getting created with one property Name with a value of Marcus, the ExpandoObject is created with two properties, Field and Value, with values Name and Marcus respectively.

Thank you.

Latest specflow versions are not supported

I like to update my projects to the latest version of SpecFlow (3.3.30) but I cannot do this because SpecFlow.Assist.Dynamic does not support this version.

I can either remove all dynamic tables and update or update this project

references mismatch

Hi there, i have installed SpecFlow 2.3.2 and SpecFlow.Assis.Dynamic 1.3.1 and after starting tests I getting exception:

Result StackTrace:
at System.ModuleHandle.ResolveType(RuntimeModule module, Int32 typeToken, IntPtr* typeInstArgs, Int32 typeInstCount, IntPtr* methodInstArgs, Int32 methodInstCount, ObjectHandleOnStack type)
at System.ModuleHandle.ResolveTypeHandleInternal(RuntimeModule module, Int32 typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
at System.Reflection.RuntimeModule.ResolveType(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
at System.Reflection.CustomAttribute.FilterCustomAttributeRecord(CustomAttributeRecord caRecord, MetadataImport scope, Assembly& lastAptcaOkAssembly, RuntimeModule decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, Object[] attributes, IList derivedAttributes, RuntimeType& attributeType, IRuntimeMethodInfo& ctor, Boolean& ctorHasParameters, Boolean& isVarArg)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes, Boolean isDecoratedTargetSecurityTransparent)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeType type, RuntimeType caType, Boolean inherit)
at System.RuntimeType.GetCustomAttributes(Type attributeType, Boolean inherit)
at TechTalk.SpecFlow.Bindings.Discovery.RuntimeBindingRegistryBuilder.BuildBindingsFromType(Type type)
at TechTalk.SpecFlow.Bindings.Discovery.RuntimeBindingRegistryBuilder.BuildBindingsFromAssembly(Assembly assembly)
at TechTalk.SpecFlow.TestRunnerManager.BuildBindingRegistry(IEnumerable1 bindingAssemblies) at TechTalk.SpecFlow.TestRunnerManager.InitializeBindingRegistry(ITestRunner testRunner) at TechTalk.SpecFlow.TestRunnerManager.CreateTestRunner(Int32 threadId) at TechTalk.SpecFlow.TestRunnerManager.GetTestRunner(Int32 threadId) at TechTalk.SpecFlow.TestRunnerManager.GetTestRunner(Assembly testAssembly, Nullable1 managedThreadId)
at Deploy.Web.API.Acceptance.Features.RefDataServersFeatureFeature.FeatureSetup(TestContext testContext)
Result Message: Class Initialization method Deploy.Web.API.Acceptance.Features.RefDataServersFeatureFeature.FeatureSetup threw exception. System.IO.FileLoadException: System.IO.FileLoadException: Could not load file or assembly 'TechTalk.SpecFlow, Version=2.1.0.0, Culture=neutral, PublicKeyToken=0778194805d6db41' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040).
Result StandardOutput: -> Using app.config

If I downgrading SpecFlow to 2.1.0 everything runs fine. But I cannot use specflow lower than 2.3.2
P.S. VisualStudio version is 15.7.1

Change to hintpath

I am having some issues with specflow .Assist in combination with Baseclass.contrib.SpecFlow.Selenium.NUnit. Basically If I add the Baseclass package, it will also install specFlow, Nunit and webDriver. Everything works fine until I add speckFlow.Assist. Once I do that the project fails to build because the hint path in the project file changes form:

..\packages\SpecFlow.1.9.0\lib\net35\TechTalk.SpecFlow.dll

To this:

..\packages\SpecFlow.Assist.Dynamic.1.0.0\lib\40\TechTalk.SpecFlow.dll

If I change it back to point at the specFlow package, then the solution builds again until I try and use table.CreateInstance(), which then can’t be found. Any ideas?

Leading zero removed is this a bug

Hi
just came accross your extension and it's brilliant I removed at least 50 classes.
However i have encountered some issues with leading zero .
When presented with something like
| myfield |07|
| myfield2 |01|
and I need the zero to be there it gets removed!
also if you have a date like this
|mydate |12/2017| and you want it to be a string it converts to a full date and then i have to reformat it.

Is there a way to make prevent to remove the zero?
In my specflow tests I treat everything as a string because eventually selenium wants always a string eg Sendkeys,

Suggestions

Forcing a particular datatype to be created

Thank you for a great bit of code. I'm wondering if there is currently a way to force a value such as '4155551212' to be interpreted as a string. Currently, it's made into a double, (4155551212.0), requiring me to do -> .ToString("F0", CultureInfo.InvariantCulture) to get it back to '4155551212'.

If I had an entire table of values that I wanted interpreted as strings, is there currently a way to force that, and bypass the decision tree you've implemented? If not, that's something I'd like to take on.

I'm imagining something like

public void TreatAllTheseValuesAs(Table table)
{
dynamic dyn = table.CreateDynamicInstance();
...
}

Ability to specify property name casing rules, or a way to match property names

I'd like the ability to specify the property name casing rules, or a way to match property names, because the current convention doesn't create the expected property names.

For example, add the following scenario in .\Specs\DynamicInstancesFromTable.feature:

Scenario: Create dynamic instance from table with specific property name
	When I create a dynamic instance from this table
		| Customer ID |
		| 123         |
	Then the CustomerID property should equal '123'

And add the following step in .\Specs\Steps\DynamicInstanceCreationSteps.cs:

        [Then(@"the CustomerID property should equal '(.*)'")]
        public void ThenTheCustomerIDPropertyShouldEqual(int expectedValue)
        {
            ((int)State.OriginalInstance.CustomerID).Should().Equal(expectedValue);
        }

Result:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : 'System.Dynamic.ExpandoObject' does not contain a definition for 'CustomerID'

The current convention will create an ExpandoObject with the property CustomerId.

The issue occurs when I try to assign the properties from the ExpandoObject to fields in the database.

In my case, the field in the database is CustomerID.

As a work-around I have to search for the property name without case sensitivity.

The issue can be resolved in two ways.

  1. Add the ability to specify one of the following property name casing rules:
    a. Do not change the case
    b. Only change the case on the first letter of every word

  2. Since I already have a type with properties I want the property names in the ExpandoObject to match with, add the ability to pass the type during the creation of the dynamic instance (using the generic syntax for example).
    I can't use SpecFlow's built-in support for creating objects because I'm updating entities in a database from the table, and I specify only the fields I want updated in the table.

Thank you.

table value is converting to date time by default

I have a table like following in my features files:

Then I should see 'View' option on following rows
| version    | temp           | promote          |
| 17.0       |                      | 2020-08-14      |
| 17.1       | 2020-08-18  |                          |
| 17.2       |                      | 2020-09-14      |
| 17.2       | 2020-09-1 5 |                          |
| 17.3       |                      | 2020-09-18      |
| 17.4       | 2020-09-28  |                          |

And In Step definition I am using CreateDynamicSet from Specflow.Assist.Dynamic(1.4.2) to get the table value:

[Then(@"I should see '(.*)' option on following rows")]
    public void ThenIShouldSeeOptionOnFollowingRows(string actionType, Table table)
    {
          
         IEnumerable<dynamic> tableData = table.CreateDynamicSet();
        foreach(var row in tableData)
        {
           

            string wcspVersion = row.version.ToString();
            string temp = row.temp.ToString();
            string promote = row.promote.ToString();

            Console.WriteLine("Test2");
            Console.WriteLine($"wcspVersion = {wcspVersion}");
            Console.WriteLine($"temp ={temp}");
            Console.WriteLine($" promote ={promote}");

            
        }
    }

While printing the value having Date like 2020-08-14 it is converting to date like 18-Aug-20 12:00:00 AM.
And While converting 17.0 to string I am getting only 17

I don't want this kind conversion. I need to get the exact value that is in the feature files. How can I get the exact value from the feature file as string?

I am getting expected result while using CreateSet

`Property value type conversions` section in wiki needs to be updated with the correct order of operations

Hi.

https://github.com/marcusoftnet/SpecFlow.Assist.Dynamic/wiki/Conversion-conventions#property-value-type-conversions needs to be updated with the correct order of operations (or maybe remove it?).

The code in the CreateTypedValue function (

private static object CreateTypedValue(string valueFromTable, bool doTypeConversion = true)
) indicates the following order:

  1. int
  2. decimal
  3. double
  4. bool
  5. DateTime
  6. string

Thank you.

Add support for additional types, specified by user.

A nice addition, would be to allow the user to add custom converters to the type-conversion.
This would give the flexibility of the Dynamic but with the freedom of creating custom types whenever this is needed.
At the moment, only the types specified below is supported.

One could utilize the IObjectContainer to register additional converters, and this could be queried in the process below.

 private static object CreateTypedValue(string valueFromTable)
        {
            // TODO: More types here?
            int i;
            if (int.TryParse(valueFromTable, out i))
                return i;

            double d;
            if (Double.TryParse(valueFromTable, out d))
                return d;

            bool b;
            if (Boolean.TryParse(valueFromTable, out b))
                return b;

            DateTime dt;
            if (DateTime.TryParse(valueFromTable, out dt))
                return dt;

            return valueFromTable;
        }

Handling reserved characters in property names

A question was raised at StackOverflow.

Right now the tool crashes when you use a C# reserved char like *&() etc.

I've been thinking quite a bit about this but this is my current idea:

  • Let this be a setting, that is turned off by default.
  • Turned off means that it crashes with a nice error message
  • Turned on the setting replaces all non-letters, non-numbers and non-underscore with an underscore. CC $ Portion Total will become CC_PortionTotal and A $trange *Title(causes problems) will become A_trange_Title_causesproblems_

I think this is cleaner and easier to understand than to try to convert all $ into S or ( into space for example.

An alternative would to simply remove the char all together, but that might cause problems for comparisons etc. This idea will at least keep the positional order.

How to create dynamic object with nested children?

I have table:

| Key                 | Value    |
| name                | testtest |
| username            | testtest |
| phone               | 33333    |
| website             | www      |
| company.name        | test     |
| company.catchPhrase | test     |
| company.bs          | test     |

I is possible to use table.CreateDynamicInstance(); to create dynamic object with nested children?
Something like json:

{
        "name": "test1232315125",
        "username": "testfdhdfh",
        "phone": "4636346236236",
        "website": "sdgsdgsdgsdgsdg",
        "company": {
            "name": "sdgsdgsdgsdg",
            "catchPhrase": "dgsdghdfjdf",
            "bs": "sdgsdgdfjfd"
        }
}

Indicate data type of values which are different in DynamicSetComparisonException.Differences

Hi.

Thank you for SpecFlow.Assist.Dynamic.

If the only differences that are found are the data type for the values of a row, it's not obvious by the messages in DynamicSetComparisonException.Differences.

For example,
In .feature file:

	Then the following data should exist
		| Field1 | Username |
		| 1      | username |

Step:

        [Then(@"the following data should exist")]
        public void ThenTheFollowingDataShouldExist(Table table)
        {
            List<dynamic> actual = this.database.GetDataFromDatabaseTable();

            try
            {
                table.CompareToDynamicSet(actual);
            }
            catch (DynamicSetComparisonException ex)
            {
                throw new Exception(string.Join(Environment.NewLine, ex.Differences), ex);
            }
        }

Exception:

TechTalk.SpecFlow.Assist.DynamicSetComparisonException: Properties differs between the table and the set
A difference was found on row '1' for column 'Field1' (property 'Field1').
	Instance:	'1'.
	Table:		'1'

In this case, the values are different only by their type.

The instance data type is dynamic {long} and the table row data type is object {int}.

I expected the exception's Differences property to indicate the data types of each of the values so it's more apparent what the actual differences are between them.

Thank you.

double.NaN is not equal to double.NaN

I am testing SpecFlow.Assist.Dynamic for some industrial application we are developing. We have a table with expected values that we are going to compare against some actual values. Some of these values are double.NaN.

It turns out that double.NaN is not considered to be the same as double.NaN (same goes for Infinity I guess). Would it be possible to fix this? It is a built in feature in c# / .net I guess, but in this particular case it does not makes no sence, so I have to reimplement the compare method if it is not fixed.

Thank you! :-)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.