集成测试断言最佳实践

Integration Test Assertion Best Practice

我最近在我的遗留应用程序上实施了集成测试,我对在集成测试中进行断言感到困惑。

在单元测试中,我们可以很容易地模拟对象,并且每次测试只有 1 个断言是有意义的。但是变成Integration Test的时候,我要验证多个场景,需要检查每一步是否正确。

可以做多个断言吗?或者是否有一些最佳实践来做到这一点?

这是我的测试代码:

   def test_new_requested_depth_purchase_create_transaction(
        self,
        requested_depth_purchase_request_1: DepthPurchaseRequestViewModel,
    ):
        """depth_purchase_created_job() should create new lead,transaction and depth transaction package"""

        self._depth_purchase_request_service.depth_purchase_created_job(
            requested_depth_purchase_request_1.original_id
        )

        crm_depth_purchase = self._depth_purchase_repo.get_by_original_id(
            requested_depth_purchase_request_1.original_id
        )
        assert crm_depth_purchase is not None

        lead = self._lead_repo.get_by_id(crm_depth_purchase.leads_id)

        assert lead is not None

        transaction = self._transaction_repo.get_by_lead_id(lead.id)

        assert transaction is not None

        transaction_packages = self._transaction_package_repo.get_all_by_transaction_id(
            transaction.id
        )

        assert len(transaction_packages) > 0
        assert all(
            [
                trx_package.type == ProductPackageConstants.ALACARTE
                and trx_package.status_id == 0
                for trx_package in transaction_packages
            ]
        )

测试框架:Pytest

是或否,视情况而定。 “集成测试”这个名字定义不清,有很多重叠的含义。
定义极端更简单:单元测试通常只有一个断言,而端到端测试有很多。考虑到这一点,有充分的理由选择多个断言还是只有一个断言。

另一种回答问题的方法是基于代码模式“Given-When-Then”。我可以像那样重新组织您的代码:

def test_new_requested_depth_purchase_create_transaction(
    self,
    requested_depth_purchase_request_1: DepthPurchaseRequestViewModel,
):
    """depth_purchase_created_job() should create new lead,transaction and depth transaction package"""
    # When
    self._depth_purchase_request_service.depth_purchase_created_job(
        requested_depth_purchase_request_1.original_id
    )

    # Then
    crm_depth_purchase = self._depth_purchase_repo.get_by_original_id(
        requested_depth_purchase_request_1.original_id
    )
    assert crm_depth_purchase is not None

    lead = self._lead_repo.get_by_id(crm_depth_purchase.leads_id)
    assert lead is not None

    transaction = self._transaction_repo.get_by_lead_id(lead.id)
    assert transaction is not None

    transaction_packages = self._transaction_package_repo.get_all_by_transaction_id(
        transaction.id
    )
    assert len(transaction_packages) > 0
    assert all(
        [
            trx_package.type == ProductPackageConstants.ALACARTE
            and trx_package.status_id == 0
            for trx_package in transaction_packages
        ]
    )

没有“Given”,因为它由 fixture requested_depth_purchase_request_1 处理。如果未注入模型,则必须创建它,结果类似于:

def test_new_requested_depth_purchase_create_transaction(self):
    # Given
    requested_depth_purchase_request_1 = some_way_to_construct_it().maybe_in_several_steps()
    
    # When
    ...

theory 中,你不应该在你的 Given 和 When 中有断言(你的测试代码应该正常工作),只在 Then 中,因为这就是测试的目的测试。但它可以作为完整性检查。

对我来说,你做的很好。做适合您(或您的团队)的事情。