20180925-4 单元测试,结对

作业要求参照[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2146]

git代码地址[https://coding.net/u/shishishaonian/p/four_arithmetic_operation]

2人结对,使用TDD测试框架 (如NUnit, JUnit, cppUnit等)完成本周作业四则运算试题生成的单元测试。

要求1 对每个功能,先给出测试用例,然后再编码功能。请注意把测试用例视为功能需求完成的检验指标。 (40分)

结对伙伴:孙赛佳

集成环境:Visual Studio 2017 

编程语言:C++

测试框架:VS中提供的本机单元测试项目

编写测试用例:

对于程序运行我们给出以下测试:

功能1,功能2

测试用例预期结果
f4出现运算表达式,换行打印?
f4后输入正确的答案答对了你真是个天才
f4后输入错误的答案再想想吧,答案似乎是x喔!,x为正确的答案
f4后共答20道题你一共答对1道题,共20道题。

功能3

测试用例预期结果
f4 -c 10按格式正确输入20道题,且有答案
f4 -c -10提示题目数量必须是 正整数。
f4 -c 1.2提示题目数量必须是 正整数。
f4 -c f提示题目数量必须是 正整数。

功能4

测试用例预期结果
f4 -c 10按格式正确输入20道带有分数的题目,且答案是分数

对于程序内部的函数我们利用VS中提供的本机单元测试项目编写测试函数进行测试。内容如下:

Is_Equal(a,b);是用来判断两个数是否相等的,也就是判断输入的答案,和试题的答案时候相等。

gcd(a, b);是用来求最大公约数的函数,在化简分数的时候需要用到。

RPNotation(st, ve);是将中缀表达式,转换为后缀表达式,是程序的核心功能。

Correct_Ans(st, correctAns);是根据后缀表达式来求出运算式的结果的。

下面给出部分测试用例的代码:

TEST_METHOD(TestMethod2)
        {
            double a = 2.0;
            double b = 2.0;
            bool test = Is_Equal(a, b);
            Assert::AreEqual<bool>(true, test);
        }
TEST_METHOD(TestMethod4)
        {
            int a = -3;
            int b = 9;
            int test = gcd(a, b);
            Assert::AreEqual<int>(3, test);
        }
TEST_METHOD(TestMethod7)
        {
            vector<char>st, ve,pt;
            string str1 = "3*2+3-4";
            for (int i = 0; i <= str1.length(); i++) {
                ve.push_back(str1[i]);
            }
            string str2 = "32*3+4-";
            for (int i = 0; i < str2.length(); i++) {
                pt.push_back(str2[i]);
            }
            RPNotation(st, ve);
            bool flag = true;
            if (st.size() != pt.size())
                flag = false;
            for (int i = 0; i < st.size(); i++) {
                if (st[i] != pt[i])
                    flag = false;
            }
            Assert::AreEqual<bool>(true, flag);
        }
TEST_METHOD(TestMethod8)
        {
            vector<char>st;
            double correctAns;
            string str1 = "32*3+4-";
            for (int i = 0; i < str1.length(); i++) {
                st.push_back(str1[i]);
            }
            Correct_Ans(st, correctAns);
            Assert::AreEqual<double>(5, correctAns);
        }

要求2 在博客报告测试用例全部fail 到 全部pass 的过程,报告事实 (fail到修改代码或者测试用例,到pass) 以及收获。 除了最初的框架,测试用例中存在一次性pass没有经过fail的,也报告一次性通过,给出如此优秀地实现了这部分功能的代码。(40分)

程序运行的测试截图

功能1,2

功能3

功能4

程序函数单元测试的截图

测试TestMethod4没有通过,仔细观察我们在求最大公因数的时候,-3和9希望得到3,但是测试没有通过,下面贴一下gcd函数。

int gcd(int a, int b) {
    return (a % b == 0) ? b : gcd(b, a % b);
}

查看代码不难发现,其结果的符号是根据a的符号得到的,但有时候结果可能是-3/9,通过程序得到的公因数是-3,结果变成了1/-3,这不是我们想要的答案。所以修改gcd,对参数的绝对值运算,可以解决这一问题。

int gcd(int m, int n) {
    int a = abs(m);
    int b = abs(n);
    return (a % b == 0) ? b : gcd(b, a % b);
}

给出中缀变后缀表达式的代码。

void RPNotation(vector<char>&st, vector<char>ve)
{
    st.clear();
    stack<char>ssign;
    for (int i = 0; i < ve.size() - 1; i++)
    {
        if (ve[i] >= '0'&&ve[i] <= '9')
            st.push_back(ve[i]);
        else
        {
            if (ssign.empty() || ve[i] == '(')
                ssign.push(ve[i]);
            else
            {
                if (ve[i] == ')')
                {
                    while (ssign.top() != '(')
                    {
                        st.push_back(ssign.top());
                        ssign.pop();
                    }
                    ssign.pop();
                }
                else
                {
                    if (ve[i] == '*' || ve[i] == '/')
                    {
                        while (!ssign.empty() && (ssign.top() == '*' || ssign.top() == '/') && ssign.top() != '(') {
                            st.push_back(ssign.top());
                            ssign.pop();
                        }
                        ssign.push(ve[i]);
                    }
                    else
                    {
                        while (!ssign.empty() && ssign.top() != '(')
                        {
                            st.push_back(ssign.top());
                            ssign.pop();
                        }
                        ssign.push(ve[i]);
                    }
                }
            }
        }
    }
    while (!ssign.empty())
    {
        st.push_back(ssign.top());
        ssign.pop();
    }
}

通过这次的作业,学会了单元测试的一些方法,以及断言的使用。由于以前没有参与过系统的开发项目,没有接触过这类的知识。开始的时候认为单元测试很繁琐,为什么不在编写时就直接测试对错呢。在逐渐的学习中,学写了两个测试用例,之后发现单元测试很直观,也很方便,同时了解到了单元测试的重要性。我们可以通过单元测试来发现自己程序中的一些隐藏的,不易被发现的bug,这对于一个程序来说是尤为重要的。

转载于:https://www.cnblogs.com/orion1994/p/9755829.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
敏捷开发模型(如极限编程)是一种适应性较强的过程模型,它主要由以下4个框架活动组成: 1. 计划:在这个活动中,开发团队和客户一起制定项目的计划和需求,制定开发计划和产品特性。这个活动的重点是建立一个开发计划和一个产品特性列表。 2. 设计:在这个活动中,开发团队和客户一起设计系统架构、编写用户故事、定义任务、创建原型等。这个活动的重点是建立一个系统架构和一个可行的设计。 3. 编码:在这个活动中,开发团队根据设计和需求,开始编写代码。这个活动的重点是实现功能、代码质量和可维护性。 4. 测试:在这个活动中,开发团队进行单元测试、集成测试、验收测试等工作,保证软件质量。这个活动的重点是确保软件符合需求和质量标准。 在编码活动中,有几个重要的实践: 1. 单元测试单元测试是一种测试方法,用于检测程序中的最小代码单元是否正常工作。单元测试可以保证代码的正确性和可维护性。 2. 结对编程:结对编程是指两个人一起编写代码,其中一个人编写代码,另一个人负责检查代码的正确性。这个实践可以改善代码质量和开发速度。 3. 重构:重构是指在不改变代码外部行为的情况下改进代码的内部结构。重构可以提高代码的可维护性和可读性。 4. 持续集成:持续集成是指开发人员将代码集成到一个共享存储库中,并自动进行编译、测试和部署。这个实践可以确保代码的稳定性和一致性。 以上这些实践之间存在着密切的关系。单元测试结对编程可以帮助开发团队确保代码质量和正确性;重构则可以帮助团队提高代码的可维护性和可读性;持续集成可以确保代码的稳定性和一致性。这些实践相互支持,共同构建了一个高质量的软件开发过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值