简体   繁体   English

维护VS Test Project中单元测试方法之间的上下文

[英]Maintain context between unit test methods in VS Test Project

I want to run the following unit tests, in order: 我想按顺序运行以下单元测试:

  1. Create new customer with a random number for name, password etc. 使用随机数创建新客户名称,密码等。
  2. Retrieve the just created customer and assert that its properties contain the same random number 检索刚刚创建的客户并断言其属性包含相同的随机数
  3. Call the ForgotPassword function on same user, with the same random number for user name 在同一用户上调用ForgotPassword函数,使用相同的用户名随机数

As seen clearly, I need to generate a random number once, and share it across 3 test methods. 如清楚所示,我需要生成一次随机数,并在3种测试方法中共享它。
I cannot seem to find a way to do that. 我似乎找不到办法做到这一点。

  • I thought of using the TestContext object, but that gets created for each instance. 我想过使用TestContext对象,但是为每个实例创建了它。
  • I tried Using the ClassInitialize() method doesn't help, as it is static, and therefore the number is not accessible by other methods. 我尝试使用ClassInitialize()方法没有帮助,因为它是静态的,因此其他方法无法访问该数字。

Any idea how to achieve my goal? 知道如何实现我的目标吗?

Can you just place your shared data into static variables? 您可以将共享数据放入静态变量吗?

Something simple like this: 像这样简单:

    private static string testValue = "something";

    [TestMethod]
    public void TestMethod1()
    {
        Assert.AreEqual(testValue, "something");
        testValue = "something2";
    }

    [TestMethod]
    public void TestMethod2()
    {
        Assert.AreEqual(testValue, "something2");
        testValue = "something3";
    }

    [TestMethod]
    public void TestMethod3()
    {
        Assert.AreEqual(testValue, "something3");
    }

Update: To summarize other comments on this question, I think that everyone is in complete agreement that keeping state between unit tests is a bad idea. 更新:总结一下这个问题的其他评论,我认为每个人都完全同意在单元测试之间保持状态是一个坏主意。 My answer was simply a way to do this, if necessary. 如果有必要,我的回答只是一种方法。 As I mentioned in another comment, I have had to do this in the past, but not for unit tests. 正如我在另一篇评论中所提到的,我过去必须这样做,但不是单元测试。 It is sometimes beneficial/necessary to keep state between integration/regression tests where you don't necessarily want to mock objects or isolate parts of the application. 在集成/回归测试之间保持状态有时是有益/必要的,您不一定要模拟对象或隔离应用程序的某些部分。 As a software tester, you do not always have the influence/ability/permission to immediately refactor or rearchitect an application to be optimal for this testing. 作为软件测试人员,您并不总是具有影响/能力/权限,可以立即重构或重新架构应用程序,使其成为此测试的最佳选择。

What you want to do here is use something like a Repository behind an IRepository interface: 你想要做的是在IRepository接口后面使用类似Repository的东西:

interface IRepository{
    Customer GetCustomer(int id);
}

You can implement a real class in your code that will query a database, but in your tests you can "Mock" this interface to return exactly what you want. 您可以在代码中实现一个查询数据库的真实类,但在测试中,您可以“模拟”此接口以准确返回您想要的内容。 Moq is my favorite - and what follows is pseudo code but hopefully you'll get the idea: Moq是我最喜欢的 - 接下来是伪代码,但希望你能得到这个想法:

[Test]
public void Customer_Should_Have_CreateAt_Set_To_Today{
  var mock = new Mock<IRepository>();
  mock.Setup(x => x.GetCustomer(100)).Returns(new Customer{id = 100, Name = "Steve"});

  var Customer = mock.Object;
  Assert.Equal(Customer.CreatedAt,Date.Today);
}

The idea here is that you control, completely, the data you need to control without relying on when an object is instantiated etc. 这里的想法是,您完全控制需要控制的数据,而不依赖于实例化对象的时间等。

It is a really bad idea to be running unit tests that share context. 运行共享上下文的单元测试是一个非常糟糕的主意。 Although I am open to suggestions, I've never come across a good reason for doing what you are suggesting. 虽然我对建议持开放态度,但我从来没有想过按照你的建议行事。

If somebody runs your tests in a different order, or in isolation, then they will fail. 如果有人以不同的顺序或单独运行您的测试,那么它们将失败。 Tests like this are termed flakey - they pass sometimes, but not others - and it isn't clear why. 像这样的测试被称为flakey - 它们有时会通过,但不会通过其他测试 - 并且不清楚为什么。

It's much better to use a mocking framework like Rhino Mocks to instantiate the mock dependencies in the state that you need. 使用像Rhino Mocks这样的模拟框架来实例化你需要的状态中的模拟依赖项要好得多。 That way, each test is a standalone test that verifies a specific thing without reference to any other tests. 这样,每个测试都是一个独立的测试,可以在不参考任何其他测试的情况下验证特定事物。

You will find it much easier to maintain tests like these, and there'll be fewer false positives and negatives in your results. 你会发现维持这样的测试要容易得多,结果中的误报和否定也会减少。

It is bad form to build unit tests with dependencies. 使用依赖项构建单元测试是不好的形式。 It is not, however, bad form to build functional tests with dependencies. 但是,构建具有依赖关系的功能测试并不是一种糟糕的形式。 In fact, it's almost required in any application with a normal level of complexity. 实际上,在任何具有正常复杂程度的应用程序中几乎都需要它。

What you're trying to do is not a unit test. 你要做的不是单元测试。 It's a functional test. 这是一个功能测试。 And you do need ot share values between test methods to accomplish things from a user's perspective. 并且您确实需要在测试方法之间使用共享值来从用户的角度来完成事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM