如何使用 TDD 定义 "limit test context"?
How to define a "limit test context" using TDD?
如何定义测试的“限制上下文”?
我这样说是因为模拟,我的服务集成了许多其他库,例如:rabbit-mq、redis 等,以及来自某个 类 的实例。然后,大部分时间我都在编写测试代码,为可以测试的服务创建“复杂”模拟。
是否可以定义这个限制?应该是一种可能的方式“不测试”这些“昂贵”的方法,只测试“简单的相关方法”,输入参数很简单,比如 sum(a, b).
很明显,测试覆盖率越高越好,但是很多很多时候编写一些有用结果值得怀疑的测试。
当将 TDD 用于定义明确的方法时,如 sum(a,b),它非常有用,但是当此方法将接收实例或使用来自另一个集成服务的实例时,模拟接收大部分尝试,而不是“方法 objective”。
想象这个service/method来测试:
class ClientService:
def ok_here_is_the_discount(self, some_args):
# Ok, receive the discount to thi signature, now is possible
# calcula the it, and response to the broker
self.calculate_user_discount_based_on_signature_type(some_args.discount_value)
def calculate_user_discount_based_on_signature_type(self, some_args):
# here will send the "result" to the broker
some_message_borker_publisher(
some_args.value - some_args.discount_signature
)
def request_the_signature_type_discount_in_another_service(self, some_args):
# Ok, I receive the client that has the signature type,
# now is need request what is the value to this signature
# in signature service
some_message_borker_publisher(
queue='siganture.service.what_discount_for_this_signature',
signature_type=some_args.client.singature_type
)
#Ok, this message goes to the broker, and the signature.service receive it
def method_that_receive_messages(self, some_args):
# Here we receives that want to calculate discount
# but just receive the client(dict/class/instance) with the signature type,
# we still dont know the value of theses discount, because when is responsible
# to manage the siganture, is the signature server
if some_args.message_type == 'please_calculate_discount':
self.request_the_signature_type_discount_in_another_service(some_args.client)
if some_args.message_type == 'message_from_signature_discount':
self.ok_here_is_the_discount(some_args.value)
1 - 它收到消息 'please_calculate_discount' 并调用方法
self.request_the_signature_type_discount_in_another_service(some_args.client)
但是还是没有折扣价值,因为这是签名服务。 (给经纪人的消息)
2 - 假设签名服务器响应 'message_from_signature_discount',然后调用方法:
self.ok_here_is_the_discount(some_args.value)
3 - 好的,方法 ok_here_is_the_discount 接收折扣并调用方法
calculate_user_discount_based_on_signature_type()
现在有计算折扣的值并将这些值发送给经纪人。
了解这些测试 (TDD) 的复杂性吗?我需要测试“method_that_receive_messages”模拟所有相关的下一个动作,或者只测试相关的方法,比如“calculate_user_discount_based_on_signature_type”?
这种情况下最好用一个真正的经纪人可以测试一下吗?
好吧,在 Python 中模拟东西很容易,但当然它仍然会带来一些开销。多年来,我一直倾向于使用模拟来设置集成测试,以测试通过系统的快乐路径,然后设计尽可能具有无副作用功能的系统,并对它们进行单元测试。然后,您可以开始 TDDing,为快乐路径设置整体测试,然后在易于测试的函数中对细节进行单元测试。
尽管 mock 背后的东西发生变化时它仍然没有用,但它在重构时提供了很好的安全感。
Python 中的模拟库很好,但有时自己编写并用 patch
替换真实的库会更容易。其实挺甜的
如何定义测试的“限制上下文”?
我这样说是因为模拟,我的服务集成了许多其他库,例如:rabbit-mq、redis 等,以及来自某个 类 的实例。然后,大部分时间我都在编写测试代码,为可以测试的服务创建“复杂”模拟。
是否可以定义这个限制?应该是一种可能的方式“不测试”这些“昂贵”的方法,只测试“简单的相关方法”,输入参数很简单,比如 sum(a, b).
很明显,测试覆盖率越高越好,但是很多很多时候编写一些有用结果值得怀疑的测试。
当将 TDD 用于定义明确的方法时,如 sum(a,b),它非常有用,但是当此方法将接收实例或使用来自另一个集成服务的实例时,模拟接收大部分尝试,而不是“方法 objective”。
想象这个service/method来测试:
class ClientService:
def ok_here_is_the_discount(self, some_args):
# Ok, receive the discount to thi signature, now is possible
# calcula the it, and response to the broker
self.calculate_user_discount_based_on_signature_type(some_args.discount_value)
def calculate_user_discount_based_on_signature_type(self, some_args):
# here will send the "result" to the broker
some_message_borker_publisher(
some_args.value - some_args.discount_signature
)
def request_the_signature_type_discount_in_another_service(self, some_args):
# Ok, I receive the client that has the signature type,
# now is need request what is the value to this signature
# in signature service
some_message_borker_publisher(
queue='siganture.service.what_discount_for_this_signature',
signature_type=some_args.client.singature_type
)
#Ok, this message goes to the broker, and the signature.service receive it
def method_that_receive_messages(self, some_args):
# Here we receives that want to calculate discount
# but just receive the client(dict/class/instance) with the signature type,
# we still dont know the value of theses discount, because when is responsible
# to manage the siganture, is the signature server
if some_args.message_type == 'please_calculate_discount':
self.request_the_signature_type_discount_in_another_service(some_args.client)
if some_args.message_type == 'message_from_signature_discount':
self.ok_here_is_the_discount(some_args.value)
1 - 它收到消息 'please_calculate_discount' 并调用方法
self.request_the_signature_type_discount_in_another_service(some_args.client)
但是还是没有折扣价值,因为这是签名服务。 (给经纪人的消息)
2 - 假设签名服务器响应 'message_from_signature_discount',然后调用方法:
self.ok_here_is_the_discount(some_args.value)
3 - 好的,方法 ok_here_is_the_discount 接收折扣并调用方法
calculate_user_discount_based_on_signature_type()
现在有计算折扣的值并将这些值发送给经纪人。
了解这些测试 (TDD) 的复杂性吗?我需要测试“method_that_receive_messages”模拟所有相关的下一个动作,或者只测试相关的方法,比如“calculate_user_discount_based_on_signature_type”?
这种情况下最好用一个真正的经纪人可以测试一下吗?
好吧,在 Python 中模拟东西很容易,但当然它仍然会带来一些开销。多年来,我一直倾向于使用模拟来设置集成测试,以测试通过系统的快乐路径,然后设计尽可能具有无副作用功能的系统,并对它们进行单元测试。然后,您可以开始 TDDing,为快乐路径设置整体测试,然后在易于测试的函数中对细节进行单元测试。
尽管 mock 背后的东西发生变化时它仍然没有用,但它在重构时提供了很好的安全感。
Python 中的模拟库很好,但有时自己编写并用 patch
替换真实的库会更容易。其实挺甜的