简体   繁体   English

如何基于外部类解决此单元测试问题?

[英]How to approach this unit-testing issue based on an external class?

I have a class Node ( add_node.py ) in which I create nodes that connect to a websocket. 我有一个class Nodeadd_node.py ),其中创建了连接到websocket的节点。 Now I want to write unit-tests for checking whether or not the connection was successful, and for checking the response of the server. 现在,我想编写单元测试来检查连接是否成功,并检查服务器的响应。

So I created a node_tests.py file which the following content: 因此,我创建了一个node_tests.py文件,其内容如下:

import unittest
import json
import re
from add_node import Node

class TestNodes(unittest.TestCase):

    def test_node_creation(self):
        self.node = Node(a='1', b='2', c=True)
        self.response = json.loads(self.node.connect())
        self.assertIn('ok', self.response['r'])

    def test_node_c(self):
        self.assertTrue(self.response['c'])

if __name__ == '__main__':
    unittest.main()

The first method is working but the second is failing because there is no attribute 'response'. 第一种方法有效,但是第二种方法失败,因为没有属性“响应”。 So how could I approach this problem? 那么我该如何解决这个问题呢?

Also, is it ok to do it they way I'm doing it? 另外,可以按照我的方式去做吗? Importing the class and writing multiple test within the same Test class? 导入该类并在同一Test类中编写多个测试?

The point of a unit test is to verify the functionality of a single isolated unit. 单元测试的重点是验证单个隔离单元的功能。 Exactly what a unit is can be debated. 究竟什么是单​​位可以争论。 Some would argue it's a single public method on a single class. 有人会说这是在单个类上的单个公共方法。 I think most would agree that is not a very useful definition though. 我认为大多数人都同意这不是一个非常有用的定义。 I like to think of them as use-cases. 我喜欢将它们视为用例。 Your tests should do one use-case, and then make one assertion about the results from that use-case. 您的测试应该做一个用例,然后对那个用例的结果进行一个断言。 This means that sometimes it's OK to let classes collaborate, and sometimes it's better to isolate a class and use test doubles for it's dependencies. 这意味着有时可以让类进行协作,有时最好隔离一个类并对其依赖项使用测试双精度。

Knowing when to isolate is something you learn over time. 随着时间的流逝,知道何时隔离是一件容易的事。 I think the most important points to consider are that every test you write should 我认为要考虑的最重要的一点是,您编写的每个测试都应

  • Fully define the context in which it's run (without depending on global state or previously run tests) 完全定义运行它的上下文(不取决于全局状态或先前运行的测试)

  • Be fast, a few milliseconds tops (this means you don't touch external resources like the file system, a web server or some database) 要快一些,几毫秒就能到达顶部(这意味着您不会触摸文件系统,Web服务器或某些数据库等外部资源)

  • Not test a bunch of other things that are covered by other tests. 不要测试其他测试涵盖的其他内容。

This third point is probably the hardest to balance. 这第三点可能是最难平衡的。 Obviously several tests will run the same code if they're making different assertions on the same use-case. 显然,如果多个测试在相同的用例上做出不同的断言,它们将运行相同的代码。 You should keep the tests small though. 不过,您应该保持较小的测试。 Let's say we want to test the cancellation process of orders in an e-commerce application. 假设我们要测试电子商务应用程序中订单的取消过程。 In this case we probably don't want to import and set up all the classes used to create, verify, etc. an order before we cancel it. 在这种情况下,我们可能不想在取消订单之前导入并设置所有用于创建,验证等的类。 In that case it's probably a better idea to just create an order object manually or maybe use a test double. 在这种情况下,最好手动创建订单对象,或者使用测试倍数。

In your case, if what you actually want to do is to test the real connection and the responses the real server gives, you don't want a unit test, you want an integration test. 在您的情况下,如果您真正想做的是测试真实的连接和真实服务器给出的响应,则您不需要单元测试,而需要集成测试。

If what you actually want is to test the business logic of your client class, however, you should probably create a fake socket/server where you can yourself define the responses and whether or not the connection is successful. 但是,如果您真正想要的是测试客户端类的业务逻辑,则可能应该创建一个伪造的套接字/服务器,您可以在其中定义响应以及连接是否成功。 This allows you to test that your client behaves correctly depending on it's communications with the remote server, without actually having to depend on the remote server in your test suite. 这样,您就可以根据与远程服务器的通信来测试客户端的行为是否正确,而不必实际依赖测试套件中的远程服务器。

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

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