ReSharper 7 EAP

Topics: ReSharper test runner
Mar 6, 2012 at 4:57 PM

Matt,

It looks like I may have convinced the JetBrains guys to support xunit natively. I suspect that could be some time though. Until then, any chance of getting a build that works with resharper 7 for VS11?

I had a look at forking and doing, but I have no clue when it comes to the ReSharper SDK unfortunately.

Cheers.

- Damian ( twitter.com/randompunter )

Coordinator
Mar 10, 2012 at 10:10 PM

You're not really giving me much motivation for this, are you? That said, it is a good excuse to get Win8/VS11 set up. I'll see what I can do.

Mar 11, 2012 at 2:48 PM
mattellis wrote:

You're not really giving me much motivation for this, are you?

Sorry, I thought native xunit support in ReSharper would be a positive thing.

Coordinator
Mar 12, 2012 at 12:15 AM

A comment on the wording, not the intent. It's a little incongruous to be told the project is soon-to-be-obsolete and in the same breath asked for a new version. It amused me, and my reply was meant with a wry smile.

Mar 12, 2012 at 2:30 PM

Fair enough :)

I strongly suspect that support will not come until 7.1 and probably later. I don't expect soon-to-be-obsolete to be soon-at-all.

In anycase I would like to offer my gratitude to you for maintaining this project even when the floor keeps moving.

Cheers.

Coordinator
Mar 23, 2012 at 7:49 AM

Right. I got a build running last night. I'll test, package and upload it as soon as I've got time. Should be up over the weekend.

Mar 23, 2012 at 9:14 AM
Edited Mar 23, 2012 at 9:14 AM

Or you could download my version of xunit runner for R#7 with cute installer https://github.com/hazzik/ReSharper.XUnitTestRunner/downloads

Coordinator
Mar 24, 2012 at 11:11 PM

You beat me @hazzik :)

I've created a new release with ReSharper 7 support.

Mar 31, 2012 at 1:39 PM

Cheers Matt

May 8, 2012 at 11:40 PM

Has this worked for anybody?

It crashed for me for 7.0.36 and doesn't seem to load at all for 7.0.18. DLLs are not blocked.

Coordinator
May 9, 2012 at 2:22 PM

I tried it the other day with build 34, and it was fine, but that doesn't mean 36 has broken something. I'll take a look tonight.

Thanks
Matt 

May 9, 2012 at 2:24 PM

Thanks Matt, that would be wonderful. The MS default test runner is a little clumsy.

Coordinator
May 9, 2012 at 8:43 PM

I've just tried against ReSharper 7.0.37, and it's working fine. I don't get any crashes.

Do you get any stack traces that might help?

Matt

May 10, 2012 at 9:28 PM
Edited Jul 9, 2012 at 7:07 AM

Hm… I don’t understand. I get no exceptions with .38 but Resharper’s unit test explorer doesn’t get populated with my tests.

Actually it doesn’t seem like Reshaper is working at all – I’m not getting the usual context menus in the editors (the Resharper menu is there)

Any ideas how to go about debugging this?

Coordinator
May 11, 2012 at 7:47 AM

The only thing I can really think of is that ReSharper is perhaps suspended. Check in VS Tools -> Options -> ReSharper.

Failing that, try running VS with the /log command line, and check the %APPDATA%\Roaming\Microsoft\VisualStudio\<version>\ActivityLog.xml file. There might be more info there.

May 11, 2012 at 9:03 AM
Edited Jul 9, 2012 at 7:08 AM

I suspended and resumed it and got my exception :)

 

Method 'GetPresentation' in type 'XunitContrib.Runner.ReSharper.UnitTestProvider.XunitTestClassElement' from assembly 'xunitcontrib.runner.resharper.provider.7.0, Version=0.5.2.40479, Culture=neutral, PublicKeyToken=null' does not have an implementation.

 

--- EXCEPTION #1/2 [TypeLoadException]

Message = “Method 'GetPresentation' in type 'XunitContrib.Runner.ReSharper.UnitTestProvider.XunitTestClassElement' from assembly 'xunitcontrib.runner.resharper.provider.7.0, Version=0.5.2.40479, Culture=neutral, PublicKeyToken=null' does not have an implementation.”

ExceptionPath = Root.InnerException

ClassName = System.TypeLoadException

HResult = COR_E_TYPELOAD=80131522

Source = xunitcontrib.runner.resharper.provider.7.0

TypeLoadClassName = XunitContrib.Runner.ReSharper.UnitTestProvider.XunitTestClassElement

TypeLoadAssemblyName = “xunitcontrib.runner.resharper.provider.7.0, Version=0.5.2.40479, Culture=neutral, PublicKeyToken=null”

TypeLoadMessageArg = GetPresentation

TypeLoadResourceID = 6012

StackTraceString = “

at XunitContrib.Runner.ReSharper.UnitTestProvider.XunitTestMetadataExplorer.ExploreTestClass(IProject project, IMetadataAssembly assembly, UnitTestElementConsumer consumer, String typeName, IEnumerable`1 methods)

at XunitContrib.Runner.ReSharper.UnitTestProvider.XunitTestMetadataExplorer.ExploreAssembly(IProject project, IMetadataAssembly assembly, UnitTestElementConsumer consumer) in c:\Users\matt\Documents\xunitcontrib\resharper\resharper60\xunitcontrib.runner.resharper.provider.6.0\XunitTestMetadataExplorer.cs:line 30

at JetBrains.ReSharper.UnitTestFramework.UnitTestBackgroundProjectExplorer.ExploreProject(IProject project, Boolean background, MetadataLoader loader) in c:\BuildAgent\work\1d5606e7e667bf54\Psi.Features\src\UnitTesting\_Core\src\UnitTestBackgroundProjectExplorer.cs:line 170

at JetBrains.ReSharper.UnitTestFramework.UnitTestBackgroundProjectExplorer.BackgroundProjectExplorer() in c:\BuildAgent\work\1d5606e7e667bf54\Psi.Features\src\UnitTesting\_Core\src\UnitTestBackgroundProjectExplorer.cs:line 256

 

--- Outer ---

 

--- EXCEPTION #2/2 [LoggerException]

Message = “Method 'GetPresentation' in type 'XunitContrib.Runner.ReSharper.UnitTestProvider.XunitTestClassElement' from assembly 'xunitcontrib.runner.resharper.provider.7.0, Version=0.5.2.40479, Culture=neutral, PublicKeyToken=null' does not have an implementation.”

ExceptionPath = Root

ClassName = JetBrains.Util.LoggerException

Data.ManagedThreadName = “Unit Test Project Explorer”

Data.PlatformSccRevision = CompiledWithoutBuildServer

Data.ProductSccRevision = CompiledWithoutBuildServer

Data.VsVersion = 11.0.50323.1

InnerException = “Exception #1 at Root.InnerException”

HResult = COR_E_APPLICATION=80131600

StackTraceString = “

at JetBrains.ReSharper.UnitTestFramework.UnitTestBackgroundProjectExplorer.BackgroundProjectExplorer() in c:\BuildAgent\work\1d5606e7e667bf54\Psi.Features\src\UnitTesting\_Core\src\UnitTestBackgroundProjectExplorer.cs:line 266

at JetBrains.Util.Logger.Catch(Action action) in c:\BuildAgent\work\1d5606e7e667bf54\Platform\src\Util\src\Logger\Logger.cs:line 243

at JetBrains.ReSharper.UnitTestFramework.UnitTestBackgroundProjectExplorer.<.ctor>b__1() in c:\BuildAgent\work\1d5606e7e667bf54\Psi.Features\src\UnitTesting\_Core\src\UnitTestBackgroundProjectExplorer.cs:line 64

at System.Threading.ThreadHelper.ThreadStart_Context(Object state)

at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)

at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)

at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

at System.Threading.ThreadHelper.ThreadStart()

Coordinator
May 11, 2012 at 9:18 AM

That's more like it. It appears the interface I need to implement has changed. I'll take a look at build 38 tonight and see if I can get a new version up soon.

Is there anything unusual about the tests you've got - nested classes, derived classes, abstract methods, virtual methods, etc? JetBrains mailed me some rs7 stack traces with this exception, but I was unable to recreate. What were you doing when it crashed? 

May 11, 2012 at 9:41 AM
Edited Jul 9, 2012 at 7:07 AM

Hm… It seems to happen when I start VS 11 beta, even on a new project (I think that I don’t even need to have XUnit tests for it to happen)

I assume it happens when RS (.39 now, did a clean reinstall just to be sure) loads the plugin

 

Isn’t this line weird? Why does it point to provider 6.0?

 

c:\Users\matt\Documents\xunitcontrib\resharper\resharper60\xunitcontrib.runner.resharper.provider.6.0\XunitTestMetadataExplorer.cs:line 30

 

Here’s the stacktrace again in case there’s anything different:

 

Method 'GetPresentation' in type 'XunitContrib.Runner.ReSharper.UnitTestProvider.XunitTestClassElement' from assembly 'xunitcontrib.runner.resharper.provider.7.0, Version=0.5.2.40479, Culture=neutral, PublicKeyToken=null' does not have an implementation.

 

--- EXCEPTION #1/2 [TypeLoadException]

Message = “Method 'GetPresentation' in type 'XunitContrib.Runner.ReSharper.UnitTestProvider.XunitTestClassElement' from assembly 'xunitcontrib.runner.resharper.provider.7.0, Version=0.5.2.40479, Culture=neutral, PublicKeyToken=null' does not have an implementation.”

ExceptionPath = Root.InnerException

ClassName = System.TypeLoadException

HResult = COR_E_TYPELOAD=80131522

Source = xunitcontrib.runner.resharper.provider.7.0

TypeLoadClassName = XunitContrib.Runner.ReSharper.UnitTestProvider.XunitTestClassElement

TypeLoadAssemblyName = “xunitcontrib.runner.resharper.provider.7.0, Version=0.5.2.40479, Culture=neutral, PublicKeyToken=null”

TypeLoadMessageArg = GetPresentation

TypeLoadResourceID = 6012

StackTraceString = “

at XunitContrib.Runner.ReSharper.UnitTestProvider.XunitTestMetadataExplorer.ExploreTestClass(IProject project, IMetadataAssembly assembly, UnitTestElementConsumer consumer, String typeName, IEnumerable`1 methods)

at XunitContrib.Runner.ReSharper.UnitTestProvider.XunitTestMetadataExplorer.ExploreAssembly(IProject project, IMetadataAssembly assembly, UnitTestElementConsumer consumer) in c:\Users\matt\Documents\xunitcontrib\resharper\resharper60\xunitcontrib.runner.resharper.provider.6.0\XunitTestMetadataExplorer.cs:line 30

at JetBrains.ReSharper.UnitTestFramework.UnitTestBackgroundProjectExplorer.ExploreProject(IProject project, Boolean background, MetadataLoader loader) in c:\BuildAgent\work\1d5606e7e667bf54\Psi.Features\src\UnitTesting\_Core\src\UnitTestBackgroundProjectExplorer.cs:line 170

at JetBrains.ReSharper.UnitTestFramework.UnitTestBackgroundProjectExplorer.BackgroundProjectExplorer() in c:\BuildAgent\work\1d5606e7e667bf54\Psi.Features\src\UnitTesting\_Core\src\UnitTestBackgroundProjectExplorer.cs:line 256

 

--- Outer ---

 

--- EXCEPTION #2/2 [LoggerException]

Message = “Method 'GetPresentation' in type 'XunitContrib.Runner.ReSharper.UnitTestProvider.XunitTestClassElement' from assembly 'xunitcontrib.runner.resharper.provider.7.0, Version=0.5.2.40479, Culture=neutral, PublicKeyToken=null' does not have an implementation.”

ExceptionPath = Root

ClassName = JetBrains.Util.LoggerException

Data.ManagedThreadName = “Unit Test Project Explorer”

Data.PlatformSccRevision = CompiledWithoutBuildServer

Data.ProductSccRevision = CompiledWithoutBuildServer

Data.VsVersion = 11.0.50323.1

InnerException = “Exception #1 at Root.InnerException”

HResult = COR_E_APPLICATION=80131600

StackTraceString = “

at JetBrains.ReSharper.UnitTestFramework.UnitTestBackgroundProjectExplorer.BackgroundProjectExplorer() in c:\BuildAgent\work\1d5606e7e667bf54\Psi.Features\src\UnitTesting\_Core\src\UnitTestBackgroundProjectExplorer.cs:line 266

at JetBrains.Util.Logger.Catch(Action action) in c:\BuildAgent\work\1d5606e7e667bf54\Platform\src\Util\src\Logger\Logger.cs:line 243

at JetBrains.ReSharper.UnitTestFramework.UnitTestBackgroundProjectExplorer.<.ctor>b__1() in c:\BuildAgent\work\1d5606e7e667bf54\Psi.Features\src\UnitTesting\_Core\src\UnitTestBackgroundProjectExplorer.cs:line 64

at System.Threading.ThreadHelper.ThreadStart_Context(Object state)

at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)

at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)

at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

at System.Threading.ThreadHelper.ThreadStart()

 

Coordinator
May 11, 2012 at 10:09 AM

The resharper60 is just the name of the folder it's in. The 7.0 plugin shares so much code with 6.0 and 6.1 that it lives in the same folder. I've renamed it resharper6x, but that doesn't help with 7.0!

May 11, 2012 at 10:11 AM
Edited Jul 9, 2012 at 7:07 AM

OK. Well, let me know if you find anything or if I can help trace the issue in any way.

By the way, I’m sure it’s irrelevant to the nature of the tests, the test project I created was an MVC4 Internet App with default unit tests but like I said I’m fairly sure the exception occurred even before I changed the tests to Xunit 

Coordinator
May 11, 2012 at 10:30 PM

Right. I've uploaded a new version for build 39 - http://xunitcontrib.codeplex.com/releases/view/84841

(And it turns out I was testing with a slightly older version than the one you downloaded, which explains why I didn't see the same crashes. Don't know why the old version worked with a newer build when the downloaded version didn't though. Ah well. This one works)

May 11, 2012 at 10:39 PM
Edited Jul 9, 2012 at 7:07 AM

I think you’ve bundled the package with xunit 1.8 and not 1.9 (can’t find the DLL!) – you probably wanna update the package :)

Coordinator
May 11, 2012 at 10:53 PM

Wow. Good spot. Copy/paste error while building the zip. Updated!

Thanks!
Matt

May 11, 2012 at 10:56 PM
Edited Jul 9, 2012 at 7:07 AM

You’re awesome. Kudos!

Jun 24, 2012 at 10:47 AM

All kinds of hell breaks loose with 7 EAP Build 73 :(

Coordinator
Jun 28, 2012 at 6:56 AM

That's not good. Sorry. I have a local build that's running against build 73, but I've made other changes to implement new features, and they aren't working properly yet. I'm planning to get a new build out with support for the latest EAPs over the weekend, so I hope you can hang on another couple of days. But thanks for letting me know!

Matt

Jun 28, 2012 at 7:11 AM

I appreciate your effort in making a free tool!

I've reverted to an old EAP build so I can work without problems and I look forward to the new features sometime after the weekend :)

Coordinator
Jul 5, 2012 at 10:30 PM

Finally got the release together. The 0.6 release supports ReSharper 7 build 82, and also provides decent Theory support.

Matt

Jul 9, 2012 at 7:11 AM

Downloading now! Thanks!

Jul 9, 2012 at 9:10 AM

Hm... when I try to debug a particular test and step into an extension method, I get a "stepping over non-user code" even though it's my code

Could this be related to your runner?

Jul 9, 2012 at 9:13 AM

No never mind, it happens when running on the console too - wth??

Coordinator
Jul 9, 2012 at 9:13 AM

Doesn't really sound related, but I can't rule anything out :)

Is the extension method in a different assembly? Is it ok for the main test method body? And is it a Fact or a Theory?

Coordinator
Jul 9, 2012 at 9:16 AM

I think the "stepping into non-user code" happens because there isn't a pdb, which is why I was asking if the extension method is in a different assembly. If it is, and that assembly doesn't have a pdb in the same folder, I think you'll see this message.

Jul 9, 2012 at 9:20 AM

This is really, really, bizarre.

It's in a different assembly but from my own project so VS builds a PDB as normal.

This is worrying, I changed method to have a throw at the start of it - it doesn't get executed.

Did a clean build and still nothing!!

Coordinator
Jul 9, 2012 at 9:25 AM

Sounds like shadow copy might have got its knickers in a twist. In the debug view check the modules window: Debug -> Windows -> Modules (I think). Look for the assembly with the extension method and see where it's being loaded from - and where the pdb is coming from. It might show it's loading from the wrong place - finding one in the gac, or an odd folder or something. If not, and it's showing a temp location from shadow copying, delete that whole shadow copy folder and try again.

Jul 9, 2012 at 9:28 AM

Loads from the right location, User code = yes and symbols are loaded... Go figure..........

Jul 9, 2012 at 9:30 AM

I hate "yield".... this method uses yield and I was using an Action to trigger it with Fluent Assertions... which is why it was never executing... they could have done a better error message......

Coordinator
Jul 9, 2012 at 12:58 PM
Ah. So does that mean it's all good?

On 9 July 2012 10:30, georgiosd <notifications@codeplex.com> wrote:

From: georgiosd

I hate "yield".... this method uses yield and I was using an Action to trigger it with Fluent Assertions... which is why it was never executing... they could have done a better error message......

Read the full discussion online.

To add a post to this discussion, reply to this email (xunitcontrib@discussions.codeplex.com)

To start a new discussion for this project, email xunitcontrib@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com


Jul 9, 2012 at 7:12 PM

Yes - sorry to have bothered you - it was happening right when I upgraded so I thought it was related :)

Nov 12, 2012 at 9:45 PM

Guess what - I've come back from the woods to give you another bug report :)

I'm using the NSpec adapter for XUnit but there's an ArgumentOutOfRangeException in your plugin - works ok with the VS2012 runner.

It seems the latest nspec + xunit adapter packages are incompatible for use this code:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml;
using NSpec;
using NSpec.Domain;
using Xunit;
using Xunit.Sdk;

namespace UnitTestProject1
{
    /// <summary>
    /// Implements an <see cref="T:ITestClassCommand"/> that can create commands to all examples contained in a given specification class.
    /// </summary>
    public class NSpecClassCommand : ITestClassCommand
    {
        /// <summary>
        /// Gets the object instance that is under test. May return null if you wish
        /// the test framework to create a new object instance for each test method.
        /// </summary>
        public object ObjectUnderTest
        {
            get
            {
                return null;
            }
        }

        /// <summary>
        /// Gets or sets the type that is being tested
        /// </summary>
        public ITypeInfo TypeUnderTest
        {
            get;
            set;
        }

        /// <summary>
        /// Allows the test class command to choose the next test to be run from the list of
        /// tests that have not yet been run, thereby allowing it to choose the run order.
        /// </summary>
        /// <param name="testsLeftToRun">The tests remaining to be run</param>
        /// <returns>
        /// The index of the test that should be run
        /// </returns>
        public int ChooseNextTest(ICollection<IMethodInfo> testsLeftToRun)
        {
            return 0;
        }

        /// <summary>
        /// Execute actions to be run after all the test methods of this test class are run.
        /// </summary>
        /// <returns>
        /// Returns the <see cref="T:System.Exception"/> thrown during execution, if any; null, otherwise
        /// </returns>
        public Exception ClassFinish()
        {
            return null;
        }

        /// <summary>
        /// Execute actions to be run before any of the test methods of this test class are run.
        /// </summary>
        /// <returns>
        /// Returns the <see cref="T:System.Exception"/> thrown during execution, if any; null, otherwise
        /// </returns>
        public Exception ClassStart()
        {
            return null;
        }

        /// <summary>
        /// Enumerates the test commands for a given test method in this test class.
        /// </summary>
        /// <param name="testMethod">The method under test</param>
        /// <returns>
        /// The test commands for the given test method
        /// </returns>
        public IEnumerable<ITestCommand> EnumerateTestCommands(IMethodInfo testMethod)
        {
            if (testMethod == null)
            {
                throw new ArgumentNullException("testMethod");
            }

            return ExampleCommand.CreateForMethod(testMethod);
        }

        /// <summary>
        /// Enumerates the methods which are test methods in this test class.
        /// </summary>
        /// <returns>
        /// The test methods
        /// </returns>
        public IEnumerable<IMethodInfo> EnumerateTestMethods()
        {
            //must inherit from nspec
            if (!this.TypeUnderTest.Type.IsSubclassOf(typeof(nspec)))
            {
                return Enumerable.Empty<IMethodInfo>();
            }

            var bindingFlags =
                BindingFlags.DeclaredOnly |
                BindingFlags.Public |
                BindingFlags.NonPublic |
                BindingFlags.Instance;

            //all instance methods that are declared in the type
            return this.TypeUnderTest.Type
                .GetMethods(bindingFlags)
                .Select(m => Xunit.Sdk.Reflector.Wrap(m));
        }

        /// <summary>
        /// Determines if a given <see cref="T:Xunit.Sdk.IMethodInfo"/> refers to a test method.
        /// </summary>
        /// <param name="testMethod">The test method to validate</param>
        /// <returns>
        /// True if the method is a test method; false, otherwise
        /// </returns>
        public bool IsTestMethod(IMethodInfo testMethod)
        {
            if (testMethod == null)
            {
                throw new ArgumentNullException("testMethod");
            }

            return testMethod.Class.Type.IsSubclassOf(typeof(nspec));
        }
    }

    /// <summary>
    /// Implements a <see cref="T:Xunit.Sdk.ITestCommand"/> that invokes all NSpec <see cref="T:NSpec.Domain.Example"/> in one method.
    /// </summary>
    internal class ExampleCommand : ITestCommand
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="T:NSpecAdapterForxUnit.ExampleCommand"/> to a specific <see cref="T:NSpec.Domain.Example"/>.
        /// </summary>
        /// <param name="method">The method that contains the <paramref name="example"/>.</param>
        /// <param name="example">The example to run.</param>
        /// <param name="instance">The instance to run the example.</param>
        /// <exception cref="T:System.ArgumentNullException">One of the arguments is <see langword="null"/>. </exception>
        public ExampleCommand(IMethodInfo method, Example example, nspec instance)
        {
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            if (example == null)
            {
                throw new ArgumentNullException("example");
            }

            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            this.Method = method;
            this.Example = example;
            this.Instance = instance;
        }

        /// <summary>
        /// Gets the method that contains the <see cref="P:Example"/>.
        /// </summary>
        /// <value>The method that contains the <see cref="P:Example"/>.</value>
        public IMethodInfo Method
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the <see cref="T:NSpec.Domain.Example"/> to run.
        /// </summary>
        /// <value>The <see cref="T:NSpec.Domain.Example"/> to run.</value>
        public Example Example
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the <see cref="NSpec.nspec"/> instance to run the example.
        /// </summary>
        /// <value>The <see cref="NSpec.nspec"/> instance to run the example.</value>
        public nspec Instance
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the display name of the test method.
        /// </summary>
        public string DisplayName
        {
            get
            {
                return Example.FullName();
            }
        }

        /// <summary>
        /// Determines if the test runner infrastructure should create a new instance of the
        /// test class before running the test.
        /// </summary>
        public bool ShouldCreateInstance
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// Determines if the test should be limited to running a specific amount of time
        /// before automatically failing.
        /// </summary>
        /// <returns>The timeout value, in milliseconds; if zero, the test will not have
        /// a timeout.</returns>
        public int Timeout
        {
            get
            {
                return 0;
            }
        }

        /// <summary>
        /// Creates the start XML to be sent to the callback when the test is about to start
        /// running.
        /// </summary>
        /// <returns>
        /// Return the <see cref="T:System.Xml.XmlNode"/> of the start node, or null if the test
        /// is known that it will not be running.
        /// </returns>
        public XmlNode ToStartXml()
        {
            return new XmlDocument().CreateElement("NSpec");
        }

        /// <summary>
        /// Executes the test method.
        /// </summary>
        /// <param name="testClass">The instance of the test class</param>
        /// <returns>
        /// Returns information about the test run
        /// </returns>
        public MethodResult Execute(object testClass)
        {
            //run the example
            try
            {
                this.Example.Context.Exercise(this.Example, this.Instance);
                if (this.Example.HasRun && !Example.Failed() && !Example.Pending) //all good. the test passed.
                {
                    return new PassedResult(
                        this.Method.Name, //methodName
                        this.Method.TypeName, //typeName
                        this.DisplayName, //displayName
                        null); //traits
                }
                else if (this.Example.Failed()) //oh noes!
                {
                    var ex = this.Example.Exception; //TODO: is this always != null?
                    while (ex.InnerException != null)
                    {
                        ex = ex.InnerException;
                    }

                    return new FailedResult(
                        this.Method.Name, //methodDate
                        this.Method.TypeName, //typeName
                        this.DisplayName, //displayName
                        null, //traits
                        ex.GetType().Name, //exceptionType
                        ex.Message, //message
                        ex.StackTrace); //stackTrace
                }
                else //TODO: this should be pending examples
                {
                    //TODO: how to mark the test as inconclusive?
                    return new SkipResult(
                        this.Method.Name, //methodName
                        this.Method.TypeName, //typeName
                        this.DisplayName, //displayName
                        null, //traits
                        "Pending"); //reason
                }
            }
            catch (Exception ex)
            {
                while (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                return new FailedResult(
                    this.Method.Name, //methodDate
                    this.Method.TypeName, //typeName
                    this.DisplayName, //displayName
                    null, //traits
                    ex.GetType().Name, //exceptionType
                    ex.Message, //message
                    ex.StackTrace); //stackTrace
            }
        }

        /// <summary>
        /// Obtains all test commands to call all examples contained in a given <see cref="T:IMethodInfo"/>.
        /// </summary>
        /// <param name="method">The method to scan.</param>
        /// <returns>All test commands to call all examples contained in <paramref name="method"/>.</returns>
        internal static IEnumerable<ITestCommand> CreateForMethod(IMethodInfo method)
        {
            //create a new instance of our specification
            var instance = method.CreateInstance() as nspec;
            if (instance == null) //not a nspec instance, nothing for us here.
            {
                return Enumerable.Empty<ITestCommand>();
            }

            var context = new MethodContext(method.MethodInfo);

            context.Build(instance);

            var commands = new List<ITestCommand>();

            BuildCommandList(method, instance, context, commands);

            return commands;
        }

        /// <summary>
        /// Recursively adds commands to all examples in a given <see cref="T:Context"/>.
        /// </summary>
        /// <param name="method">The method where the examples belong.</param>
        /// <param name="instance">The <see cref="T:nspec"/> instance.</param>
        /// <param name="context">The parent context.</param>
        /// <param name="commands">A list where the commands will be stored.</param>
        private static void BuildCommandList(IMethodInfo method, nspec instance, Context context, List<ITestCommand> commands)
        {
            foreach (var example in context.Examples)
            {
                commands.Add(new ExampleCommand(method, example, instance));
            }

            foreach (var childContext in context.ChildContexts())
            {
                BuildCommandList(method, instance, childContext, commands);
            }
        }
    }

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public sealed class SpecificationAttribute : FactAttribute
    {
        /// <summary>
        /// Enumerates the test commands represented by this test method. Derived classes should
        /// override this method to return instances of <see cref="T:Xunit.Sdk.ITestCommand"/>, one per execution
        /// of a test method.
        /// </summary>
        /// <param name="method">The test method</param>
        /// <returns>
        /// The test commands which will execute the test runs for the given method
        /// </returns>
        /// <remarks>
        /// Returns all child examples in all contexts.
        /// </remarks>
        protected override IEnumerable<ITestCommand> EnumerateTestCommands(IMethodInfo method)
        {
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            return ExampleCommand.CreateForMethod(method);
        }
    }



    public class describe_specifications : nspec
    {
        [Specification]
        public void when_creating_specifications()
        {
            //some of these specifications are meant to fail so you can see what the output looks like
            it["true should be false"] = () => true.should_be_false();
            it["enumerable should be empty"] = () => new int[] { }.should_be_empty();
            it["enumerable should contain 1"] = () => new[] { 1 }.should_contain(1);
            it["enumerable should not contain 1"] = () => new[] { 1 }.should_not_contain(1);
            it["1 should be 2"] = () => 1.should_be(2);
            it["1 should be 1"] = () => 1.should_be(1);
            it["1 should not be 1"] = () => 1.should_not_be(1);
            it["1 should not be 2"] = () => 1.should_not_be(2);
            it["\"\" should not be null"] = () => "".should_not_be_null();
            it["some object should not be null"] = () => someObject.should_not_be_null();
            //EXPERIMENTAL - specify only takes a lambda and does
            //its best to make a sentence out of the code. YMMV.
            specify = () => "ninja".should_not_be("pirate");
        }
        object someObject = null;
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml;
using NSpec;
using NSpec.Domain;
using Xunit;
using Xunit.Sdk;

namespace UnitTestProject1
{
    /// <summary>
    /// Implements an <see cref="T:ITestClassCommand"/> that can create commands to all examples contained in a given specification class.
    /// </summary>
    public class NSpecClassCommand : ITestClassCommand
    {
        /// <summary>
        /// Gets the object instance that is under test. May return null if you wish
        /// the test framework to create a new object instance for each test method.
        /// </summary>
        public object ObjectUnderTest
        {
            get
            {
                return null;
            }
        }

        /// <summary>
        /// Gets or sets the type that is being tested
        /// </summary>
        public ITypeInfo TypeUnderTest
        {
            get;
            set;
        }

        /// <summary>
        /// Allows the test class command to choose the next test to be run from the list of
        /// tests that have not yet been run, thereby allowing it to choose the run order.
        /// </summary>
        /// <param name="testsLeftToRun">The tests remaining to be run</param>
        /// <returns>
        /// The index of the test that should be run
        /// </returns>
        public int ChooseNextTest(ICollection<IMethodInfo> testsLeftToRun)
        {
            return 0;
        }

        /// <summary>
        /// Execute actions to be run after all the test methods of this test class are run.
        /// </summary>
        /// <returns>
        /// Returns the <see cref="T:System.Exception"/> thrown during execution, if any; null, otherwise
        /// </returns>
        public Exception ClassFinish()
        {
            return null;
        }

        /// <summary>
        /// Execute actions to be run before any of the test methods of this test class are run.
        /// </summary>
        /// <returns>
        /// Returns the <see cref="T:System.Exception"/> thrown during execution, if any; null, otherwise
        /// </returns>
        public Exception ClassStart()
        {
            return null;
        }

        /// <summary>
        /// Enumerates the test commands for a given test method in this test class.
        /// </summary>
        /// <param name="testMethod">The method under test</param>
        /// <returns>
        /// The test commands for the given test method
        /// </returns>
        public IEnumerable<ITestCommand> EnumerateTestCommands(IMethodInfo testMethod)
        {
            if (testMethod == null)
            {
                throw new ArgumentNullException("testMethod");
            }

            return ExampleCommand.CreateForMethod(testMethod);
        }

        /// <summary>
        /// Enumerates the methods which are test methods in this test class.
        /// </summary>
        /// <returns>
        /// The test methods
        /// </returns>
        public IEnumerable<IMethodInfo> EnumerateTestMethods()
        {
            //must inherit from nspec
            if (!this.TypeUnderTest.Type.IsSubclassOf(typeof(nspec)))
            {
                return Enumerable.Empty<IMethodInfo>();
            }

            var bindingFlags =
                BindingFlags.DeclaredOnly |
                BindingFlags.Public |
                BindingFlags.NonPublic |
                BindingFlags.Instance;

            //all instance methods that are declared in the type
            return this.TypeUnderTest.Type
                .GetMethods(bindingFlags)
                .Select(m => Xunit.Sdk.Reflector.Wrap(m));
        }

        /// <summary>
        /// Determines if a given <see cref="T:Xunit.Sdk.IMethodInfo"/> refers to a test method.
        /// </summary>
        /// <param name="testMethod">The test method to validate</param>
        /// <returns>
        /// True if the method is a test method; false, otherwise
        /// </returns>
        public bool IsTestMethod(IMethodInfo testMethod)
        {
            if (testMethod == null)
            {
                throw new ArgumentNullException("testMethod");
            }

            return testMethod.Class.Type.IsSubclassOf(typeof(nspec));
        }
    }

    /// <summary>
    /// Implements a <see cref="T:Xunit.Sdk.ITestCommand"/> that invokes all NSpec <see cref="T:NSpec.Domain.Example"/> in one method.
    /// </summary>
    internal class ExampleCommand : ITestCommand
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="T:NSpecAdapterForxUnit.ExampleCommand"/> to a specific <see cref="T:NSpec.Domain.Example"/>.
        /// </summary>
        /// <param name="method">The method that contains the <paramref name="example"/>.</param>
        /// <param name="example">The example to run.</param>
        /// <param name="instance">The instance to run the example.</param>
        /// <exception cref="T:System.ArgumentNullException">One of the arguments is <see langword="null"/>. </exception>
        public ExampleCommand(IMethodInfo method, Example example, nspec instance)
        {
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            if (example == null)
            {
                throw new ArgumentNullException("example");
            }

            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            this.Method = method;
            this.Example = example;
            this.Instance = instance;
        }

        /// <summary>
        /// Gets the method that contains the <see cref="P:Example"/>.
        /// </summary>
        /// <value>The method that contains the <see cref="P:Example"/>.</value>
        public IMethodInfo Method
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the <see cref="T:NSpec.Domain.Example"/> to run.
        /// </summary>
        /// <value>The <see cref="T:NSpec.Domain.Example"/> to run.</value>
        public Example Example
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the <see cref="NSpec.nspec"/> instance to run the example.
        /// </summary>
        /// <value>The <see cref="NSpec.nspec"/> instance to run the example.</value>
        public nspec Instance
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the display name of the test method.
        /// </summary>
        public string DisplayName
        {
            get
            {
                return Example.FullName();
            }
        }

        /// <summary>
        /// Determines if the test runner infrastructure should create a new instance of the
        /// test class before running the test.
        /// </summary>
        public bool ShouldCreateInstance
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// Determines if the test should be limited to running a specific amount of time
        /// before automatically failing.
        /// </summary>
        /// <returns>The timeout value, in milliseconds; if zero, the test will not have
        /// a timeout.</returns>
        public int Timeout
        {
            get
            {
                return 0;
            }
        }

        /// <summary>
        /// Creates the start XML to be sent to the callback when the test is about to start
        /// running.
        /// </summary>
        /// <returns>
        /// Return the <see cref="T:System.Xml.XmlNode"/> of the start node, or null if the test
        /// is known that it will not be running.
        /// </returns>
        public XmlNode ToStartXml()
        {
            return new XmlDocument().CreateElement("NSpec");
        }

        /// <summary>
        /// Executes the test method.
        /// </summary>
        /// <param name="testClass">The instance of the test class</param>
        /// <returns>
        /// Returns information about the test run
        /// </returns>
        public MethodResult Execute(object testClass)
        {
            //run the example
            try
            {
                this.Example.Context.Exercise(this.Example, this.Instance);
                if (this.Example.HasRun && !Example.Failed() && !Example.Pending) //all good. the test passed.
                {
                    return new PassedResult(
                        this.Method.Name, //methodName
                        this.Method.TypeName, //typeName
                        this.DisplayName, //displayName
                        null); //traits
                }
                else if (this.Example.Failed()) //oh noes!
                {
                    var ex = this.Example.Exception; //TODO: is this always != null?
                    while (ex.InnerException != null)
                    {
                        ex = ex.InnerException;
                    }

                    return new FailedResult(
                        this.Method.Name, //methodDate
                        this.Method.TypeName, //typeName
                        this.DisplayName, //displayName
                        null, //traits
                        ex.GetType().Name, //exceptionType
                        ex.Message, //message
                        ex.StackTrace); //stackTrace
                }
                else //TODO: this should be pending examples
                {
                    //TODO: how to mark the test as inconclusive?
                    return new SkipResult(
                        this.Method.Name, //methodName
                        this.Method.TypeName, //typeName
                        this.DisplayName, //displayName
                        null, //traits
                        "Pending"); //reason
                }
            }
            catch (Exception ex)
            {
                while (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                return new FailedResult(
                    this.Method.Name, //methodDate
                    this.Method.TypeName, //typeName
                    this.DisplayName, //displayName
                    null, //traits
                    ex.GetType().Name, //exceptionType
                    ex.Message, //message
                    ex.StackTrace); //stackTrace
            }
        }

        /// <summary>
        /// Obtains all test commands to call all examples contained in a given <see cref="T:IMethodInfo"/>.
        /// </summary>
        /// <param name="method">The method to scan.</param>
        /// <returns>All test commands to call all examples contained in <paramref name="method"/>.</returns>
        internal static IEnumerable<ITestCommand> CreateForMethod(IMethodInfo method)
        {
            //create a new instance of our specification
            var instance = method.CreateInstance() as nspec;
            if (instance == null) //not a nspec instance, nothing for us here.
            {
                return Enumerable.Empty<ITestCommand>();
            }

            var context = new MethodContext(method.MethodInfo);

            context.Build(instance);

            var commands = new List<ITestCommand>();

            BuildCommandList(method, instance, context, commands);

            return commands;
        }

        /// <summary>
        /// Recursively adds commands to all examples in a given <see cref="T:Context"/>.
        /// </summary>
        /// <param name="method">The method where the examples belong.</param>
        /// <param name="instance">The <see cref="T:nspec"/> instance.</param>
        /// <param name="context">The parent context.</param>
        /// <param name="commands">A list where the commands will be stored.</param>
        private static void BuildCommandList(IMethodInfo method, nspec instance, Context context, List<ITestCommand> commands)
        {
            foreach (var example in context.Examples)
            {
                commands.Add(new ExampleCommand(method, example, instance));
            }

            foreach (var childContext in context.ChildContexts())
            {
                BuildCommandList(method, instance, childContext, commands);
            }
        }
    }

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public sealed class SpecificationAttribute : FactAttribute
    {
        /// <summary>
        /// Enumerates the test commands represented by this test method. Derived classes should
        /// override this method to return instances of <see cref="T:Xunit.Sdk.ITestCommand"/>, one per execution
        /// of a test method.
        /// </summary>
        /// <param name="method">The test method</param>
        /// <returns>
        /// The test commands which will execute the test runs for the given method
        /// </returns>
        /// <remarks>
        /// Returns all child examples in all contexts.
        /// </remarks>
        protected override IEnumerable<ITestCommand> EnumerateTestCommands(IMethodInfo method)
        {
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            return ExampleCommand.CreateForMethod(method);
        }
    }



    public class describe_specifications : nspec
    {
        [Specification]
        public void when_creating_specifications()
        {
            //some of these specifications are meant to fail so you can see what the output looks like
            it["true should be false"] = () => true.should_be_false();
            //it["enumerable should be empty"] = () => new int[] { }.should_be_empty();
            //it["enumerable should contain 1"] = () => new[] { 1 }.should_contain(1);
            //it["enumerable should not contain 1"] = () => new[] { 1 }.should_not_contain(1);
            //it["1 should be 2"] = () => 1.should_be(2);
            //it["1 should be 1"] = () => 1.should_be(1);
            //it["1 should not be 1"] = () => 1.should_not_be(1);
            //it["1 should not be 2"] = () => 1.should_not_be(2);
            //it["\"\" should not be null"] = () => "".should_not_be_null();
            //it["some object should not be null"] = () => someObject.should_not_be_null();
            ////EXPERIMENTAL - specify only takes a lambda and does
            ////its best to make a sentence out of the code. YMMV.
            //specify = () => "ninja".should_not_be("pirate");
        }
        object someObject = null;
    }
}
Coordinator
Nov 14, 2012 at 6:14 PM

OK, there are really two problems here. Firstly, you're not giving the ReSharper runner exception details in the format it's expecting, and secondly, the ReSharper runner isn't handling exception details in the wrong format correctly. I'll fix the second one, I'll let you fix the first.

You need to change your calls to new FailedResult() - either use the overload that lets you pass in the exception directly, or use xunit's ExceptionUtility.GetMessage and ExceptionUtility.GetStackTrace. These two helper methods get the message and stack trace, *including inner exceptions*, and in so doing change the format slightly. I have to confess that I don't like this, as I have to parse the strings to get proper exception information back out again - I would have preferred arrays of strings or somesuch. Regardless, my parsing doesn't like it when you give it a normal message that hasn't been formatted to include the exception type. I'll get that fixed for the next release.

Nov 14, 2012 at 8:56 PM
Thanks for looking into it but I've concluded the plugin is too incomplete to be of any use.
Basically it creates the nspec context purely based on the method which means that beforeEach and other such nice things won't work.

I've also concluded the wisest thing for me would be to write a VS11 unit test discoverer/runner for nspec, separate from xunit.
This is because the nspec discovery model seems to match more that of VS11 than that of xunit

If I do get round to it I'll release the source - let me know if you'd like to take a look and I'll post here.


From: [email removed]
To: [email removed]
Date: Wed, 14 Nov 2012 11:14:35 -0800
Subject: Re: ReSharper 7 EAP [xunitcontrib:347526]

From: mattellis
OK, there are really two problems here. Firstly, you're not giving the ReSharper runner exception details in the format it's expecting, and secondly, the ReSharper runner isn't handling exception details in the wrong format correctly. I'll fix the second one, I'll let you fix the first.
You need to change your calls to new FailedResult() - either use the overload that lets you pass in the exception directly, or use xunit's ExceptionUtility.GetMessage and ExceptionUtility.GetStackTrace. These two helper methods get the message and stack trace, *including inner exceptions*, and in so doing change the format slightly. I have to confess that I don't like this, as I have to parse the strings to get proper exception information back out again - I would have preferred arrays of strings or somesuch. Regardless, my parsing doesn't like it when you give it a normal message that hasn't been formatted to include the exception type. I'll get that fixed for the next release.
Read the full discussion online.
To add a post to this discussion, reply to this email (xunitcontrib@discussions.codeplex.com)
To start a new discussion for this project, email xunitcontrib@discussions.codeplex.com
You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.
Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com
Coordinator
Nov 15, 2012 at 10:27 AM

Well, I don't know anything about the beforeEach, but you can get much better results with a few tweaks to ExampleCommand (I couldn't leave it not quite working :). As well as formatting the FailedResult exception details correctly, if you derive from TestCommand and use its ToStartXml, things start working a whole lot better - each "it" statement is treated like a Theory, and gets a new node under the method in ReSharper's test runner tree.

Here are the changes to the ExampleCommand (I split all of the files out):

(And I've just noticed there's a GitHub repo. I should probably send a pull request with these changes)

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using NSpec;
using NSpec.Domain;
using Xunit.Sdk;

namespace UnitTestProject1
{
    /// <summary>
    /// Implements a <see cref="T:Xunit.Sdk.ITestCommand"/> that invokes all NSpec <see cref="T:NSpec.Domain.Example"/> in one method.
    /// </summary>
    internal class ExampleCommand : TestCommand
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="T:NSpecAdapterForxUnit.ExampleCommand"/> to a specific <see cref="T:NSpec.Domain.Example"/>.
        /// </summary>
        /// <param name="method">The method that contains the <paramref name="example"/>.</param>
        /// <param name="example">The example to run.</param>
        /// <param name="instance">The instance to run the example.</param>
        /// <exception cref="T:System.ArgumentNullException">One of the arguments is <see langword="null"/>. </exception>
        public ExampleCommand(IMethodInfo method, Example example, nspec instance)
            : base(method, example.FullName(), 0)
        {
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            if (example == null)
            {
                throw new ArgumentNullException("example");
            }

            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            this.Method = method;
            this.Example = example;
            this.Instance = instance;
        }

        /// <summary>
        /// Gets the method that contains the <see cref="P:Example"/>.
        /// </summary>
        /// <value>The method that contains the <see cref="P:Example"/>.</value>
        public IMethodInfo Method
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the <see cref="T:NSpec.Domain.Example"/> to run.
        /// </summary>
        /// <value>The <see cref="T:NSpec.Domain.Example"/> to run.</value>
        public Example Example
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the <see cref="NSpec.nspec"/> instance to run the example.
        /// </summary>
        /// <value>The <see cref="NSpec.nspec"/> instance to run the example.</value>
        public nspec Instance
        {
            get;
            private set;
        }

        /// <summary>
        /// Determines if the test runner infrastructure should create a new instance of the
        /// test class before running the test.
        /// </summary>
        public override bool ShouldCreateInstance
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// Executes the test method.
        /// </summary>
        /// <param name="testClass">The instance of the test class</param>
        /// <returns>
        /// Returns information about the test run
        /// </returns>
        public override MethodResult Execute(object testClass)
        {
            //run the example
            try
            {
                this.Example.Context.Exercise(this.Example, this.Instance);
                if (this.Example.HasRun && !Example.Failed() && !Example.Pending) //all good. the test passed.
                {
                    return new PassedResult(
                        this.Method.Name, //methodName
                        this.Method.TypeName, //typeName
                        this.DisplayName, //displayName
                        null); //traits
                }
                else if (this.Example.Failed()) //oh noes!
                {
                    var ex = this.Example.Exception; //TODO: is this always != null?
                    while (ex.InnerException != null)
                    {
                        ex = ex.InnerException;
                    }

                    return new FailedResult(Method, ex, DisplayName);
                }
                else //TODO: this should be pending examples
                {
                    //TODO: how to mark the test as inconclusive?
                    return new SkipResult(
                        this.Method.Name, //methodName
                        this.Method.TypeName, //typeName
                        this.DisplayName, //displayName
                        null, //traits
                        "Pending"); //reason
                }
            }
            catch (Exception ex)
            {
                while (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                return new FailedResult(Method, ex, DisplayName);
            }
        }

        /// <summary>
        /// Obtains all test commands to call all examples contained in a given <see cref="T:IMethodInfo"/>.
        /// </summary>
        /// <param name="method">The method to scan.</param>
        /// <returns>All test commands to call all examples contained in <paramref name="method"/>.</returns>
        internal static IEnumerable<ITestCommand> CreateForMethod(IMethodInfo method)
        {
            //create a new instance of our specification
            var instance = method.CreateInstance() as nspec;
            if (instance == null) //not a nspec instance, nothing for us here.
            {
                return Enumerable.Empty<ITestCommand>();
            }

            var context = new MethodContext(method.MethodInfo);

            context.Build(instance);

            var commands = new List<ITestCommand>();

            BuildCommandList(method, instance, context, commands);

            return commands;
        }

        /// <summary>
        /// Recursively adds commands to all examples in a given <see cref="T:Context"/>.
        /// </summary>
        /// <param name="method">The method where the examples belong.</param>
        /// <param name="instance">The <see cref="T:nspec"/> instance.</param>
        /// <param name="context">The parent context.</param>
        /// <param name="commands">A list where the commands will be stored.</param>
        private static void BuildCommandList(IMethodInfo method, nspec instance, Context context, List<ITestCommand> commands)
        {
            foreach (var example in context.Examples)
            {
                commands.Add(new ExampleCommand(method, example, instance));
            }

            foreach (var childContext in context.ChildContexts())
            {
                BuildCommandList(method, instance, childContext, commands);
            }
        }
    }


Coordinator
Nov 15, 2012 at 10:28 AM

Also, with my JetBrains plugin evangelist hat on, a ReSharper nspec test runner plugin could be interesting, too...

Nov 15, 2012 at 9:17 PM
Wow, you re fast!

It would indeed be wonderful though a vs11 test plugin may make more sense given the "run tests on build" feature that R# is lacking afaik.

Re the example command, if you look at the nspec source, ContextBuilder, you ll see that the context is built as a tree and not monolithic as in the case on this nspec xunit adaptation. I still havent figured out how to build it partially.

And to be honest, im annoyed at the spaghetti that you get with nspec that im considering writing my own bdd test framework. You up for it? :)

Sent from my iPad

On 15 Νοε 2012, at 21:46, "mattellis" <notifications@codeplex.com> wrote:

From: mattellis

Also, with my JetBrains plugin evangelist hat on, a ReSharper nspec test runner plugin could be interesting, too...

Coordinator
Nov 16, 2012 at 8:42 AM

Oh no, I'm not going to start writing test frameworks. That's just crazy talk :) No, I'm happy to push my tweaks to the nspec adapter back, but I'm not going to start anything new...

Nov 16, 2012 at 9:05 AM
Hehe, crazy indeed. But I'm very frustrated by the state of BDD test frameworks so I may just attempt it and see how it goes.
I'm not saying the outcome will be better than what's already out there, but if it is, I'm sure I'll sway you into the odd pull request :P



From: [email removed]
To: [email removed]
Date: Fri, 16 Nov 2012 01:42:27 -0800
Subject: Re: ReSharper 7 EAP [xunitcontrib:347526]

From: mattellis
Oh no, I'm not going to start writing test frameworks. That's just crazy talk :) No, I'm happy to push my tweaks to the nspec adapter back, but I'm not going to start anything new...
Read the full discussion online.
To add a post to this discussion, reply to this email (xunitcontrib@discussions.codeplex.com)
To start a new discussion for this project, email xunitcontrib@discussions.codeplex.com
You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.
Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com
Coordinator
Nov 16, 2012 at 9:33 AM

I know, I'm easily swayed. BTW, where's the "run on build" feature of vs11? I'm having a play, but can't find it.

And resharper doesn't have a feature for this - my guess being that you can just run all tests or the current session and that forces a build anyway - so instead of hitting ctrl+shift+B, hit ctrl+T, R and you've got the same feature. That said, I did see a VS extension that might be interesting: http://visualstudiogallery.msdn.microsoft.com/5dca9c5c-29cf-4fd7-b3ff-573e5776f0bd?SRC=VSIDE

Nov 16, 2012 at 11:11 AM
It's under Test -> Test Settings -> Run tests after build
But the Resharper plugin looks awesome too!


From: [email removed]
To: [email removed]
Date: Fri, 16 Nov 2012 02:33:17 -0800
Subject: Re: ReSharper 7 EAP [xunitcontrib:347526]

From: mattellis
I know, I'm easily swayed. BTW, where's the "run on build" feature of vs11? I'm having a play, but can't find it.
And resharper doesn't have a feature for this - my guess being that you can just run all tests or the current session and that forces a build anyway - so instead of hitting ctrl+shift+B, hit ctrl+T, R and you've got the same feature. That said, I did see a VS extension that might be interesting: http://visualstudiogallery.msdn.microsoft.com/5dca9c5c-29cf-4fd7-b3ff-573e5776f0bd?SRC=VSIDE
Read the full discussion online.
To add a post to this discussion, reply to this email (xunitcontrib@discussions.codeplex.com)
To start a new discussion for this project, email xunitcontrib@discussions.codeplex.com
You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.
Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com
Nov 30, 2012 at 12:26 PM
I ended up switching to SpecFlow - I thought I'd find the Gherkin editor annoying but it's actually pretty neat - I like the data/scenario + implementation separation.
NSpec was doing my head in with all the nested lambdas.
Just a heads up :)


From: [email removed]
To: [email removed]
Date: Fri, 16 Nov 2012 02:33:17 -0800
Subject: Re: ReSharper 7 EAP [xunitcontrib:347526]

From: mattellis
I know, I'm easily swayed. BTW, where's the "run on build" feature of vs11? I'm having a play, but can't find it.
And resharper doesn't have a feature for this - my guess being that you can just run all tests or the current session and that forces a build anyway - so instead of hitting ctrl+shift+B, hit ctrl+T, R and you've got the same feature. That said, I did see a VS extension that might be interesting: http://visualstudiogallery.msdn.microsoft.com/5dca9c5c-29cf-4fd7-b3ff-573e5776f0bd?SRC=VSIDE
Read the full discussion online.
To add a post to this discussion, reply to this email (xunitcontrib@discussions.codeplex.com)
To start a new discussion for this project, email xunitcontrib@discussions.codeplex.com
You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.
Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com