C# 将参数传递给dotnet测试项目?

C# 将参数传递给dotnet测试项目?,c#,automated-tests,integration-testing,.net-core,C#,Automated Tests,Integration Testing,.net Core,我在Visual Studio 2017的.NET Core 1.1单元测试项目(不是xUnit测试项目)中有下面的测试类。如何将命令行参数传递给TestMethod [TestClass] public class TestClass { [TestMethod] public void TestMethod() { var args = Environment.GetCommandLineArgs(); var json = JsonC

我在Visual Studio 2017的.NET Core 1.1单元测试项目(不是xUnit测试项目)中有下面的测试类。如何将命令行参数传递给
TestMethod

[TestClass]
public class TestClass
{
    [TestMethod]
    public void TestMethod()
    {
        var args = Environment.GetCommandLineArgs();
        var json = JsonConvert.SerializeObject(args);
        throw new Exception(json);
    }
}
互联网上的很多地方让人觉得你可以在你想要传递的参数前面放一个
--
,但我无法让它工作

以下是我尝试过的命令:

  • dotnet TestProject.csproj--hello=world
  • dotnet TestProject.csproj--hello world
  • dotnet TestProject.csproj--hello world
但他们每次都会输出这个信息。注意
hello
world
都不存在:

[“C:\Users\\\\\\.nuget\packages\microsoft.testplatform.testhost\15.0.0\lib\netstandard1.5\testhost.dll”、“--port”、“55032”、“--parentprocessid”、“24440”]

第一个字符串只是正在运行的程序集的名称--。我不知道
--port
--parentprocessid
参数来自哪里

此外,这些变化使得
dotnet测试
阻塞
提供的一个或多个运行设置包含无效令牌(原文如此):

  • dotnet TestProject.csproj--hello=world
  • dotnet TestProject.csproj--hello=world

编辑:它看起来像
GetCommandLineArgs()
,即使它在这里工作

还有,他说:

这些类的实例化方式使VS可以对它们进行单元测试,这与正常执行完全不同。可执行文件的运行方式与正常运行方式不同,您和VS都不能为其提供参数。通过使用二进制文件作为类库,这些类在程序执行时被独立实例化。(原文如此)

我想知道这是否仍然适用于
dotnet测试

在其他新闻中,有人怀疑命令行参数是否可以传递给DLL,但:

[函数原型:]无效回调入口点(HWND HWND,HINSTANCE hinst,LPSTR lpszCmdLine,int-nCmdShow)

[Rundll]调用函数,传递命令行尾部,该尾部是


我想我完全搞错了。将以下两种情况结合起来可能是最好的方法

选项1:从集成测试重构到单元测试
TestMethod
现在是一个集成测试,而不是单元测试,因为它依赖于命令行参数

如果我重构
TestMethod
,使其从如下接口获取命令行参数:

interface IArgumentsProvider
{
    IEnumerable<string> GetArguments();
}
接口IArgumentsProvider
{
IEnumerable GetArguments();
}
…然后将
TestMethod
转换为单元测试,其中可以模拟
IArgumentsProvider
,以便只测试
TestMethod
中的功能(这是单元测试的定义)

请注意,我可能希望随后将该接口的非模拟实现上的测试移动到其他集成测试所在的位置。见下文

选项2:将集成测试从单元测试项目移到部署管道中的其他地方 将测试重构为单元测试并不总是可能的。例如,在某个时候,您可能希望在将代码发布到野外之前,确保位置控制器能够从SQL数据库中发布和检索地理坐标


这是一个集成测试的例子。集成测试属于部署管道中的其他地方:与其让测试作为单元测试项目中构建定义的一部分执行,不如将其移动到发布定义中,并从更合适的框架中调用它。

这是我在搜索此答案时遇到的一个地方,所以我在这里分享我的工作是公平的

目前,无法将参数传递给任何.net测试项目。您可以使用mstest testsettings/runsettings文件,但这需要创建单独的文件。在我的例子中,我需要一个服务器名和密码来进行Selenium编码的UI测试,我不想存储它们

传递参数的推荐方法之一是通过环境变量。因此,在C#xunit文件中,您可以执行以下操作:

// in mytest.cs
var user = Environment.GetEnvironmentVariable("TestUser");
var password = Environment.GetEnvironmentVariable("TestPassword");
var url = Environment.GetEnvironmentVariable("TestUrl");
如果您不想确定地设置环境变量,请记住,您可以仅为会话进程临时设置它们。一种方法是创建一个简单的cmd文件

#launchtests.cmd
SETLOCAL
SET TestUser='pete001'
SET TestPassword='secret'
SET TestUrl='http://testserver.local/login'
DOTNET TEST mytest.csproj
现在是有趣的部分。您可以参数化此过程的每个方面。因此,您可以将其更改为:

#run wity launchtests.cmd pete001 secret 'http://testserver.local/login'
SETLOCAL
SET %1
SET %2
SET %3
DOTNET TEST mytest.csproj
或者,如果您想从Azure DevOps(fka VSTS或TFS)管道启动测试,您可以简单地使用$(…)符号来内联变量,即使它们被标记为机密和/或来自Azure KeyVault

#In AzureDevops, variables not marked as secret are already added to the environment
SET TestPassword=$(TestPassword)
dotnet test $(Build.SourcesDirectory)\MyCompany.MyProduct.UITests\MyTest.csproj --configuration $(BuildConfiguration) --collect "Code Coverage" --logger trx --results-directory $(Agent.TempDirectory)

您可以像这样将Runsettings传递给测试运行程序(例如bash):

对于其他shell类型,这显然是一个正确转义的问题,正如您将看到的,这可能是一个痛苦的问题。对于MSTest,可通过以下方式访问参数:

var args = TestContext.Properties["YourTestProject.Args"].Split();

这意味着
dotnet test
的味道不适合在需要对代码保密的情况下运行集成测试,这正是我想让它做的。我的解决方案中有单元测试和集成测试。1个项目用于单元,另一个项目用于集成。如何将变量传递到集成测试项目中?我需要将只有在CICD期间构建时才知道的变量传递到测试中,以便它知道如何/在何处进行测试。@JerrodHorton假设您的意思是有两个
dotnet test
项目,我发现
dotnet test
是错误的集成测试框架。相反,您可以考虑创建一个单独的控制台应用程序,这些应用程序可以生成并传递那些生成时间变量。或者,我相信还有其他伟大的fram
var args = TestContext.Properties["YourTestProject.Args"].Split();