当前位置: 首页 > article >正文

第22章 走进xUnit:测试驱动开发的关键工具(持续探索)

写在前面


这本书是我们老板推荐过的,我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后,我突然思考,对于测试开发工程师来说,什么才更有价值呢?如何让 AI 工具更好地辅助自己写代码,或许优质的单元测试是一个切入点。 就我个人而言,这本书确实很有帮助。第一次读的时候,很多细节我都不太懂,但将书中内容应用到工作中后,我受益匪浅。比如面对一些让人抓狂的代码设计时,书里的方法能让我逐步深入理解代码的逻辑与设计。 作为一名测试开发工程师,我想把学习这本书的经验分享给大家,希望能给大家带来帮助。因为现在工作中大多使用 Python 代码,所以我把书中JAVA案例都用 Python 代码进行了改写 。

在前面几篇博客中,我们围绕xUnit测试框架进行了多方面的探索,包括测试的准备、清理、计数等功能的实现。本篇博客将聚焦于如何处理未通过的测试用例,进一步完善我们对xUnit框架的理解与实践。

处理未通过用例的测试需求

在测试过程中,准确识别和处理未通过的测试用例至关重要。我们需要编写更精细的测试,以确保在有测试未通过的情况下,能够正确地记录和报告相关信息。具体来说,我们期望testStarted()和testFailed()等方法能够在测试开始和失败时,将对应消息准确发送到结果当中,以便正确输出测试结果。

代码实现步骤

编写测试方法验证结果格式化

首先,在TestCaseTest类中编写testFailedResultFormatting方法,用于验证测试失败结果的格式化是否正确:

class TestCaseTest(TestCase):
    def testFailedResultFormatting(self):
        result = TestResult()
        result.testStarted()
        result.testFailed()
        assert "1 run, 1 failed" == result.summary()

更新TestResult类以记录失败次数

为了准确记录测试失败的次数,对TestResult类进行如下更新:

class TestResult:
    def __init__(self):
        self.runCount = 0
        self.errorCount = 0

    def testStarted(self):
        self.runCount = self.runCount + 1

    def testFailed(self):
        self.errorCount = self.errorCount + 1

    def summary(self):
        return "%d run, %d failed" % (self.runCount, self.errorCount)

修改TestCase类的run方法以捕获异常

在TestCase类的run方法中,通过try - except语句捕获测试方法抛出的异常,并调用result.testFailed()来记录测试失败:

class TestCase:
    def __init__(self, name):
        self.name = name

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def run(self):
        result = TestResult()
        result.testStarted()
        self.setUp()
        try:
            method = getattr(self, self.name)
            method()
        except:
            result.testFailed()
        self.tearDown()
        return result

潜在问题与待办事项

在上述代码实现中,存在一个潜在问题:如果在setUp()方法执行过程中出现严重问题,产生的异常将不会被捕获。这与我们期望测试彼此独立运行的初衷不符。我们将此问题记录在待办事项中,后续再进行处理。

完整示例代码

class TestResult:
    def __init__(self):
        self.runCount = 0
        self.errorCount = 0

    def testStarted(self):
        self.runCount = self.runCount + 1

    def testFailed(self):
        self.errorCount = self.errorCount + 1

    def summary(self):
        return "%d run, %d failed" % (self.runCount, self.errorCount)


class TestCase:
    def __init__(self, name):
        self.name = name

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def run(self):
        result = TestResult()
        result.testStarted()
        self.setUp()
        try:
            method = getattr(self, self.name)
            method()
        except:
            result.testFailed()
        self.tearDown()
        return result


class WasRun:
    def __init__(self, name):
        self.name = name
        self.wasRun = None
        self.log = ""

    def setUp(self):
        self.wasRun = None
        self.log = "setUp "

    def testMethod(self):
        self.wasRun = 1
        self.log = self.log + "testMethod"

    def tearDown(self):
        self.log = self.log + " tearDown"

    def testBrokenMethod(self):
        raise Exception


class TestCaseTest(TestCase):
    def testFailedResultFormatting(self):
        result = TestResult()
        result.testStarted()
        result.testFailed()
        assert "1 run, 1 failed" == result.summary()

本章小结

回顾本章内容,我们完成了以下关键任务:

  • 编写了粒度更小的测试方法testFailedResultFormatting,用于验证测试失败结果的正确性。
  • 更新了TestResult类,使其能够准确记录测试运行次数和失败次数,并正确格式化测试结果。
  • 修改了TestCase类的run方法,实现了对测试方法异常的捕获和测试失败的记录。
  • 注意到setUp()方法中可能存在的异常捕获问题,并将其列入待办事项。

通过对未通过测试用例处理的研究,我们的xUnit测试框架在功能完善的道路上又前进了一步。后续,我们将着手解决待办事项,并探索如何让多个测试一起运行,持续提升测试框架的实用性和稳定性。


http://www.kler.cn/a/519606.html

相关文章:

  • Spring Boot(6)解决ruoyi框架连续快速发送post请求时,弹出“数据正在处理,请勿重复提交”提醒的问题
  • Day39:列表的索引
  • erase() 【删数函数】的使用
  • 用Python和PyQt5打造一个股票涨幅统计工具
  • @RabbitListener处理重试机制完成后的异常捕获
  • php代码审计2 piwigo CMS in_array()函数漏洞
  • 凝“华”聚智,“清”创未来-----华清远见教育科技集团成都中心2024年度总结大会暨2025新春盛典
  • 【论文阅读】HumanPlus: Humanoid Shadowing and Imitation from Humans
  • 蓝桥杯之c++入门(一)【第一个c++程序】
  • 27. 【.NET 8 实战--孢子记账--从单体到微服务】--简易报表--报表服务
  • Docker 系列之 docker-compose 容器编排详解
  • 【信息系统项目管理师-选择真题】2017上半年综合知识答案和详解
  • Transfoemr的解码器(Decoder)与分词技术
  • QT:控件属性及常用控件(4)-----多元素控件、容器类控件、布局管理器
  • 3.numpy练习(2)
  • RabbitMQ 分布式高可用
  • 【Linux】Linux编译器-g++、gcc、动静态库
  • 7、知识库内容更新与自动化
  • 系统编程(线程互斥)
  • 牛角棋项目实践1:牛角棋的定义和用python实现简单功能
  • 大模型开发 | RAG在实际开发中可能遇到的坑
  • rewrite规则
  • STL中的list容器
  • 汇编的使用总结
  • CSS:跑马灯
  • 使用MQTT.fx向阿里云物理网平台上报物理模型数据