IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> TDD测试驱动开发 -> 正文阅读

[开发测试]TDD测试驱动开发


本文是参照依着风睡_hcg博主的文章写的,[链接地址],如有错误的地方,欢迎大家讨论 链接地址

什么是测试驱动开发

测试驱动开发(Test-Driven Development),是敏捷开发中的一项核心实践和技术。
TDD是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么代码产品,之后再开始真正的业务需求开发。

测试驱动开发该怎么做?

我们只要记住三部曲就可以了,变红–>变绿–>重构,现在你可能还不理解这是什么意思,看完以下的文章就懂啦!
在这里插入图片描述

基于Junit的简单实操

在进行 TDD 案例编写的时候,看一个简单的需求(经典案例):

  • 输入一个非元音字符,并预期返回字符本身 (输入"h" 返回“h”)
  • 输入一个元音(a,e,i,o,u),返回 mommy (输入"a" 返回“mommy”)
  • 输入一个元音超过字符串的30%,元音字母被 mommy 替换(输入"ab" 返回“mommyb”)
  • 输入一个元音超过30%,并且存在连续元音的字符串,并预期只被替换一次(输入"aab" 返回“mommyab”)

如果直接进行代码编写,靠大脑分析分析整理代码的逻辑,和书写步骤的时候比较繁琐。
那么接下来就看下这个案例在 TDD 中如何逐步成型的吧。

需求一:输入一个非元音字符,并预期返回字符本身 (输入"h" 返回“h”)

  • 第一步:首先编写测试用例代码,运行。结果变红
    。(测试用例未通过)

@Test
public void test(){
	String inputStr = "h";
	String result = tddTest(inputStr);
	Assert.assertEquals("h", result);
}
 
 
public String tddTest(String inputStr){
	return null;
}
  • 第二步:编写业务逻辑代码,运行。变绿
    (测试用例通过)
public String tddTest(String inputStr){
	return inputStr;
}
  • 第三步:检查是否需要重构,这个需求不需要重构

需求二:输入一个元音(a,e,i,o,u),返回 mommy (输入"a" 返回“mommy”)

第一步:加入新的业务逻辑(输入元音字母返回特定的字符串)运行。结果变红
(测试用例未通过)

@Test
public void test1(){
	String inputStr = "h";
	String result = tddTest(inputStr);
	Assert.assertEquals("h", result);
}
 
@Test
public void test2(){
	String inputStr = "a";
	String result = tddTest(inputStr);
	Assert.assertEquals("mommy", result);
}
 
 
public String tddTest(String inputStr){
		return inputStr;
}

  • 第二步:编写业务逻辑代码,运行。变绿
    (测试用例通过)
public String tddTest(String inputStr){
	List<String> list = Arrays.asList("a","e","i","o","u");
	if(list.contains(inputStr)){
		return "mommy";
	}else{
		return inputStr;
	}
  • 第三步:检查是否需要重构,这个需求不需要重构

需求三:加入新的业务逻辑(元音字符超过字符串的 30% ,被特定字符串替换)运行结果变红

  • 第一步:加入新的业务逻辑(元音字符超过字符串的 30% ,被特定字符串替换)运行。结果变红
    (测试用例未通过)
 @Test
    public void test1() {
        String inputStr = "h";
        String result = tddTest(inputStr);
        Assert.assertEquals("h", result);
    }
    @Test
    public void test2() {
        String inputStr = "a";
        String result = tddTest(inputStr);
        Assert.assertEquals("mommy", result);
    }
    @Test
    public void test3() {
        String inputStr = "ab";
        String result = tddTest(inputStr);
        Assert.assertEquals("mommyb", result);
    }
  • 第二步:编写业务逻辑代码,运行。变绿
    (测试用例通过)
 public String tddTest(String inputStr) {
        List<String> list = Arrays.asList("a", "e", "i", "o", "u");
        StringBuffer ret = new StringBuffer();
        int count = 0;
        for(int i = 0; i < inputStr.length(); i++) {
            char ch = inputStr.charAt(i);
            if(list.contains(ch + "")) {
                count++;
            }else{
                continue;
            }
        }
        if((float)count / (float)inputStr.length() > 0.3) {
            for(int i = 0; i < inputStr.length(); i++) {
                char ch = inputStr.charAt(i);
                if(list.contains(ch + "")) {
                    ret.append("mommy");
                }else{
                    ret.append(ch + "");
                }
            }
        }else{
            return inputStr;
        }
        return ret.toString();
    }
  • 第三步:检查是否需要重构,这个需求导致tddTest()函数的代码变得有点荣誉,所以需要进行代码的重构

计算元音在字符传中的数量,是一个独立的逻辑,可以进行方法抽取

 private static int getYuanyinCount(List list, String inputStr) {
        int count = 0;
        for(int i = 0; i < inputStr.length(); i++) {
            char ch = inputStr.charAt(i);
            if(list.contains(ch + "")) {
                count++;
            }else{
                continue;
            }
        }
        return count;
    }

也可以对元音替换方法进行抽取

 private static String replace(List list, String inputStr) {
        StringBuffer ret = new StringBuffer();
        for(int i = 0; i < inputStr.length(); i++) {
            char ch = inputStr.charAt(i);
            if(list.contains(ch + "")) {
                ret.append(REPLACE_CONSTANT);
            }else{
                ret.append(ch + "");
            }
        }
        return ret.toString();
    }

最后 : 对数字和字符串进行定义常量

{
    private final static double VOWEL_PERCENT = 0.3;
	private final static String REPLACE_CONSTANT = "mommy";
}

重构后的代码是以下代码:是不是看起来简洁了许多,而且也易于维护和拓展

   	private final static double VOWEL_PERCENT = 0.3;
    private final static String REPLACE_CONSTANT = "mommy";
    private static int getYuanyinCount(List list, String inputStr) {
        int count = 0;
        for(int i = 0; i < inputStr.length(); i++) {
            char ch = inputStr.charAt(i);
            if(list.contains(ch + "")) {
                count++;
            }else{
                continue;
            }
        }
        return count;
    }

    private static String replace(List list, String inputStr) {
        StringBuffer ret = new StringBuffer();
        for(int i = 0; i < inputStr.length(); i++) {
            char ch = inputStr.charAt(i);
            if(list.contains(ch + "")) {
                ret.append(REPLACE_CONSTANT);
            }else{
                ret.append(ch + "");
            }
        }
        return ret.toString();
    }

    public String tddTest(String inputStr) {
        List<String> list = Arrays.asList("a", "e", "i", "o", "u");
        int count = getYuanyinCount(list, inputStr);
        if((float)count / (float)inputStr.length() > VOWEL_PERCENT) {
            return replace(list, inputStr);
        }else{
            return inputStr;
        }
    }

需求四:加入新的业务逻辑(连续元音的字符串,并预期只被替换一次)运行结果变红

  • 第一步:加入新的业务逻辑连续元音的字符串,并预期只被替换一次)运行。结果变红
    (测试用例未通过)
  @Test
    public void test4() {
        String inputStr = "aaabb";
        String result = tddTest(inputStr);
        Assert.assertEquals("mommyaabb", result);
    }

第二步:修改业务逻辑,由于对元音替换我们前面已经进行了方法抽取,所以没必要在主方法中进行修改开发。变绿
(测试用例通过)

 private static String replace(List list, String inputStr) {
        StringBuffer ret = new StringBuffer();
        int i = 0;
        while(i < inputStr.length()) {
            char ch = inputStr.charAt(i);
            if(list.contains(ch + "")) {
                ret.append(REPLACE_CONSTANT);
                while(i < inputStr.length() - 1 && inputStr.charAt(i + 1) == ch) {
                    ret.append(ch + "");
                    i++;
                }
            }else{
                ret.append(ch + "");
            }
            i++;
        }
        return ret.toString();
    }

自此,开发基本完成,我又对多种情况的可能性,进尽可能的减少,行了进一步的修改和完善,使得 bug 数量以及后续的维护尽可能的减少。其中可能存在大量的不完美的代码和不健全的业务逻辑,如果读者有发现可以和我提出来,尽可能的改善。

完整代码

import org.junit.Assert;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;

public class testDemo {

    private final static double VOWEL_PERCENT = 0.3;
    private final static String REPLACE_CONSTANT = "mommy";

    @Test
    public void test1() {
        String inputStr = "h";
        String result = tddTest(inputStr);
        Assert.assertEquals("h", result);
    }
    @Test
    public void test2() {
        String inputStr = "a";
        String result = tddTest(inputStr);
        Assert.assertEquals("mommy", result);
    }
    @Test
    public void test3() {
        String inputStr = "ab";
        String result = tddTest(inputStr);
        Assert.assertEquals("mommyb", result);
    }
    @Test
    public void test4() {
        String inputStr = "aaabb";
        String result = tddTest(inputStr);
        Assert.assertEquals("mommyaabb", result);
    }

    private static int getYuanyinCount(List list, String inputStr) {
        int count = 0;
        for(int i = 0; i < inputStr.length(); i++) {
            char ch = inputStr.charAt(i);
            if(list.contains(ch + "")) {
                count++;
            }else{
                continue;
            }
        }
        return count;
    }

    private static String replace(List list, String inputStr) {
        StringBuffer ret = new StringBuffer();
        int i = 0;
        while(i < inputStr.length()) {
            char ch = inputStr.charAt(i);
            if(list.contains(ch + "")) {
                ret.append(REPLACE_CONSTANT);
                while(i < inputStr.length() - 1 && inputStr.charAt(i + 1) == ch) {
                    ret.append(ch + "");
                    i++;
                }
            }else{
                ret.append(ch + "");
            }
            i++;
        }
        return ret.toString();
    }

    public String tddTest(String inputStr) {
        List<String> list = Arrays.asList("a", "e", "i", "o", "u");
        int count = getYuanyinCount(list, inputStr);
        if((float)count / (float)inputStr.length() > VOWEL_PERCENT) {
            return replace(list, inputStr);
        }else{
            return inputStr;
        }
    }
}

测试全部通过
在这里插入图片描述

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-03-17 22:30:22  更:2022-03-17 22:31:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 0:13:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码