Closed synek317 closed 3 years ago
Hi
I don't mind re-releasing; I think that the problem is more likely that there's a dependency in my package.nuspec
which is:
<dependency id="NUnit" version="[3.10.1,4)"/>
Now, the last time I dealt with this package was quite long ago, according to nuspec docs, meaning "any version of NUnit >= 3.10.1 and < 4"; though I could have been wrong (I drew on https://docs.microsoft.com/en-us/nuget/concepts/package-versioning#version-ranges)
Hint paths within the csproj should only refer to when builds happen at my machine - when you use the package, your machine should be trying to resolve the assembly via other means.
What version of NUnit are you using? How are you trying to install NUnit.StaticExpect
? Perhaps we can figure out the correct solution together (:
for reference, if I start up a new nunit test project (defaults to net50) with dotnet new nunit -n consume r
and install nunit.staticexpect
, I can dotnet test
with the following UnitTest1.cs:
using NUnit.Framework;
using static NUnit.StaticExpect.Expectations;
namespace consumer
{
public class Tests
{
[Test]
public void Test1()
{
Expect(1, EqualTo(1));
}
}
}
(with the minor caveat that I needed to manually install the latest Microsoft.Net.Test.Sdk package as the one installed with dotnet new nunit
fails with cert errors)
I'm not sure if you have modern (sdk-style) csproj files or the older style - if so, I'll have to try repro with an older-style one; example above was done on Linux.
for reference, this is the .csproj that dotnet new
created (with a little help from me, as outlined above):
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="microsoft.net.test.sdk" Version="16.8.3" />
<PackageReference Include="NUnit" Version="3.13.1" />
<PackageReference Include="nunit.staticexpect" Version="1.0.7" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
</ItemGroup>
</Project>
My usecase is a bit more complicated - I'm porting a project, also on Linux, that currently uses mono. Its target is currently net45 but can be easily upgraded to net471. I'm using net461 though since, as far as I understand, it is the first that implements netstandard20.
To run tests on CI, I use nunit3-console. To do the development and run tests in the latest MonoDevelop. My runtime is Mono 6.12
This is the minimal example that causes an error:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="3.13.1" />
<PackageReference Include="NUnit.StaticExpect" Version="1.0.7" />
</ItemGroup>
</Project>
using NUnit.Framework;
using static NUnit.StaticExpect.Expectations;
namespace NUnitStaticExpectTest
{
class Tests
{
[Test]
public void Foo()
{
Expect(1, Is.EqualTo(2));
}
}
}
Error:
System.IO.FileNotFoundException : Could not load file or assembly 'nunit.framework, Version=3.10.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb' or one of its dependencies.
It works well if I change the referenced NUnit version from 3.13 to 3.10.1.
Ok, so what I think is going on here is that when I build with dotnet, I'm getting automatic assembly rebinds happening for me such that the version NUnit.StaticExpect is compiled against (the venerable 3.10.1.0) is bound upward to whatever assembly version is in the package 3.13.1 (my asmdeps util shows that to be at 3.12.0.0). So what I'd suggest is adding an assembly rebind to your app.config for this, something like:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="nunit.framework" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.12.0.0" newVersion="3.12.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
(you may already have a runtime
or assemblyBinding
node, so edit as appropriate)
alternatively edit your .csproj, in the PropertyGroup
where you have your TargetFramework
, add:
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
let me know if this helps (:
Hi, I've tried it before, both ideas. I've also copy-pasted your code and used it in my dummy project and it still doesn't work, unfortunately.
In the meantime, I've published NUnit.StaticExpect without the
Now I'm confused. I don't understand why MonoDevelop cannot just use the newer version. When I run tests from the command line, using msbuild and nunit3-console, it works just fine. I'm 100% sure there is no other .NET installed on my computer other than mono 6.12.
is it possible to share the repo with the code so I can take a look? more eyes -> maybe we find something?
In the meantime, I've published NUnit.StaticExpect without the and to my local nuget and, surprisingly, it didn't help too.
it's not that surprising really: the error comes because NUnit.StaticExpect assemblies, when loaded, are looking for nunit.framework at version 3.10.1.0 and you have something else on disk. This is why an assembly-rebind should have worked - but the rebind has to happen at the top-most assembly (from my experience) for it to work, which is probably why it's working from the console, but not from MonoDevelop. If you were to upgrade NUnit.StaticExpect's version of nunit.framework in your local copy and put that nugpkg in your local nuget repo, I bet it would work.
I could dig out a new release just with the latest nunit.framework, if that works for you. This package may be deprecated, but I don't like leaving people in the lurch :D
Wow, thank you SO MUCH!
Meanwhile, I've created a project you requested: https://github.com/synek317/NUnitStaticExpectTest
There, I put two tests that create a file. One uses a function from NUnit.StaticExpect and another one doesn't. The latter always works, the first one works when I use NUnit 3.10.1 OR when I run tests from using the nunit3-console runner.
Thanks to the files created during the tests, I've noticed that the working directory is different in both cases (bin/Debug/net461 when using MonoDevelop vs ./ when using nunit3-console). In the csproj, you can see quite a lot of properties that I've been testing but none of them worked for me.
And btw., I also think that nuget / msbuild are smart enough to understand semver. Even some of the metadata (e.g. project.assets.json in the obj/) marked the dependency as [3.10.1, 4.0.0). It should not require assembly rebind. My guess is it is something with either MonoDevelop or the code used by MD to execute tests (not sure what it is).
I think that MonoDevelop is bypassing your assembly rebind somehow; remember that nuget package versions don't have to mirror the versions of their contained assemblies, so, yes, Nuget is doing the right thing with respect to semver, but, as you've experienced, that throws MD for a loop. I'll re-release, simply bumping the nunit dependency.
btw, one of the reasons I deprecated was because I wrote my own assertions library, NExpect
, which does have different syntax (so I don't expect you to adopt it, but give it a go if you're so inclined - it offers some benefits over NUnit's assertions, like deep equality testing and easy extensibility), but the other was because I was releasing a new version of NUnit.StaticExpect at least once a week, and only because NUnit versions were bumped - no changes to NUnit.StaticExpect; so at that point I thought that the assembly rebind route was good enough and opened up the upper package version for NUnit.StaticExpect.
yeah, also looks like NUnit dropped support for netstandard1.4, so I have to bump that to netstandard2.0, which you can consume from net461 :\
ok, I've pushed version 2.0.0 - I did a major increment because I've had to drop support for netstandard1.4 and there's a new overload of Match
that upstream NUnit supports, but I don't.
Wow, thanks again! It works just fine with 2.0.0 and net461 (which I choose exactly having in mind it is the first net4xy that supports netstandard2.0).
MonoDevelop is not getting much love recently but well, that's why I'm moving towards .net core :)
np, glad I could help
Hi, I know the project is deprecated, but I work on a project that has thousands of tests that depend on this library and as far as I know, there is no automated way of migrating them.
I'm migrating from .NET 4.5 to .NET 5 and found out that this library forces me to use NUnit 3.10.1
I think this might be the root cause:
Do you think you would be able to remove these lines, check if it compiles on your machine, and then publish a new version?