zoukankan      html  css  js  c++  java
  • 实验五 单元测试

    一、实验目的

    1)掌握单元测试的方法

    2) 学习XUnit测试原理及框架;

    3)掌握使用测试框架进行单元测试的方法和过程。

    二、实验内容

    1、源码

    #include <stdio.h>
    #include <stdlib.h>
    #define MAX 20
    //定义两个栈,分别存放运算数和运算符
    struct SNode_Num
    {
    int datas[MAX];
    int top;
    };
    typedef struct SNode_Num OperateNum;
    struct SNode_Symbol
    {
    char symbol[MAX];
    int top;
    };
    typedef struct SNode_Symbol OperateSymbol;

    //取出相应的数
    int GetOperateNum(OperateNum *StackNum)
    {
    return StackNum->datas[StackNum->top];
    }

    //取出相应运算符
    char GetOperateSymbol(OperateSymbol *StackSymbol)
    {
    return StackSymbol->symbol[StackSymbol->top];
    }

    //运算数进栈
    void PushOperateNum(OperateNum *StackNum, int x)
    {
    StackNum->top++;
    StackNum->datas[StackNum->top] = x;
    }

    //运算符进栈
    void PushOperateSymbol(OperateSymbol *StackSymbol, char ch)
    {
    StackSymbol->top++;
    StackSymbol->symbol[StackSymbol->top] = ch;
    }

    //运算数退栈
    int PopOperateNum(OperateNum *StackNum)
    {
    int num;
    num = StackNum->datas[StackNum->top];
    StackNum->top--;
    return num;
    }

    //运算符退栈
    char PopOperateSymbol(OperateSymbol *StackSymbol)
    {
    char ch;
    ch = StackSymbol->symbol[StackSymbol->top];
    StackSymbol->top--;
    return ch;
    }

    //判断输入的符号是否是四则运算符号
    int IsOperateSymbolOrNum(char ch)
    {
    if(ch == '+' || ch == '-' || ch == '*'|| ch == '/' || ch == ' ') return 1;
    else return 0;
    }

    //判断符号的优先级
    char Priority(char inputnum, char ch)
    {
    switch(inputnum)
    {
    //加减在同一个优先级上
    case '+':
    case '-':
    {
    if(ch == '+' || ch == '-') return '>';
    else if(ch == '*' || ch == '/') return '<';
    else return '>';
    }
    break;

    //乘除在同一优先级
    case '*':
    case '/':
    {
    if(ch == '+' || ch == '-') return '>';
    else if(ch == '*' || ch == '/') return '>';
    else return '>';
    }
    break;

    case ' ':
    {
    if(ch == ' ') return '=';
    else return '<';
    }
    break;
    }
    }
    int Calculate(int num1, char ch, int num2)
    {
    int result;
    switch(ch)
    {
    case '+':
    result = num1 + num2;
    break;
    case '-':
    if(num1<num2)
    result=-1000;
    else
    result=num1-num2;
    break;
    case '*':
    result = num1 * num2;
    break;
    case '/':
    if(num1%num2==0)
    result = num1 / num2;
    else
    result=-1000;
    }
    return result;
    }
    //用于用户输入和计算结果
    int MainCalc()
    {
    //主函数进行计算
    OperateNum datas;
    OperateSymbol symbol;
    int num1, num2, result, num;
    char ch, sign;
    //初始化顺序栈
    datas.top=-1; //操作数栈顶指针
    symbol.top=-1; //操作符栈顶指针
    //把回车计算的操作符放在栈中
    PushOperateSymbol(&symbol, ' ');
    ch = getchar();
    while((ch != ' ') || (GetOperateSymbol(&symbol) != ' '))
    {
    if(!IsOperateSymbolOrNum(ch))
    {
    num = atoi(&ch); //将字符转换为整数
    ch = getchar(); //获取输入
    while(!IsOperateSymbolOrNum(ch))
    {
    num = num * 10 + atoi(&ch);
    ch = getchar(); //当没有输入回车时,继续获取输入
    }
    PushOperateNum(&datas, num);
    }
    else
    {
    //考虑第一个数是负数的情况
    if(ch=='-'&&symbol.top==0&&datas.top==-1)PushOperateNum(&datas, 0);
    switch(Priority(GetOperateSymbol(&symbol), ch))
    {
    //判断优先级后进行计算
    case '<':
    PushOperateSymbol(&symbol, ch);
    ch = getchar();
    break;
    case '=':
    sign = PopOperateSymbol(&symbol);
    ch = getchar(); //获取输入
    break;
    case '>':
    sign = PopOperateSymbol(&symbol);
    num2 = PopOperateNum(&datas);
    num1 = PopOperateNum(&datas);
    result = Calculate(num1, sign, num2);
    PushOperateNum(&datas, result);
    break;

    }
    }
    }
    result = GetOperateNum(&datas);
    return result;
    }

    int main(int argc, char *argv[])
    {
    int result,cj=0,answer,i;

    for(i=0;i<10;){
    getchar();
    printf("请第%d出题:",i+1);
    result = MainCalc();
    if(result>=0){
    i++;
    printf("请输入你的答案:");
    scanf("%d",&answer);
    if(result==answer){
    cj+=10;
    printf("恭喜您答对了 ");
    }
    else{
    printf("哦,您答错了,正确答案是:%d ",result);
    }
    }
    else{
    printf("不符合规则,请重新出题 ");
    }

    }
    printf("您答对了%d题 ",cj/10);
    printf("您的总分为%d ",cj);
    }

    2、测试用例设计

    四则混合运算中运算顺序的问题

    测试用例:2+3*2

    运算结果出现分数会不报错

    测试用例:7/3

     

      3、选择的测试框架介绍、安装过程

    一个MinUnit测试实例是一个通过测试则返回0(NULL)的函数。如果测试失败,这个函数应该返回一个测试失败的描述字符串。mu_assert 是一个当表达式失败时返回字符串的宏。而宏mu_runtest重复调用测试实例直到测试实例失败。这就是MinUnit的全部。就没有安装过程了

      4 测试代码

    运行测试

    mu_run_test(test)

    运行测试函数 int test();同时统计成功和失败的次数

    mu_test_results()

    显示测试结果,包括成功和失败的测试数量

      5测试结果与分析

     创建一个miniunit.h文件,并在主程序中调用即可。

    push测试报告和测试代码到各自的github仓库

    我的github地址:https://github.com/zhanglingluan233/-

     图上所示的四则运算是我的代码。

    思考题

    我是觉得工匠一的做法比较好,

    根据我查阅的资料:

    作者:腾讯技术工程
    链接:https://www.zhihu.com/question/28729261/answer/1058317111
    来源:知乎

    下面这张图,来自微软的统计数据:bug在单元测试阶段被发现,平均耗时3.25小时,如果漏到系统测试阶段,要花费11.5小时。

    下面这张图,旨在说明两个问题:85%的缺陷都在代码设计阶段产生,而发现bug的阶段越靠后,耗费成本就越高,指数级别的增高。所以,在早期的单元测试就能发现bug,省时省力,一劳永逸,何乐而不为呢

    由上述说明已经非常明确的表明了,不论是砌砖,还是编写程序,越晚发现错误,越会花费更多的时间精力和金钱,所以要做好单元测试,虽然他会花费一些时间,但是为了代码可以重复运行,要做好维护。

    小结

    1、针对C语言的测试框架相比其他语言要少一些,开始打算使用CUnit,结果网上面找不到CUnit的源码包,CUnit官网也打不开,可能是我的问题。或许是更多的新语言出现了?网络上对这个软件的教程都是很多年前的了。我最后使用了miniuint框架。

    2、C语言的测试框架与Java、python有很大不同。比如JUnit就是全功能的单元测试模板。

    3、我之前在一个网站上做过C语言的练习题,它就是可以自动测试我编写的C语言程序是否正确。用户界面是只能看见五个用例是否通过,没有测试用例的具体信息,我从来没想过这个用例是需要人为思考添加的。这次试验让我知道了一个程序更幕后的工作,也对”程序“的编写有了更多的了解,程序不仅仅是编写出来,测试等等这些“善后”的工作也帮助程序变得更加完善。

  • 相关阅读:
    爬虫基础
    设计BBS
    中间件和auth模块
    git
    分页器与form表单
    cookie与session
    springboot2.x基础教程:@Enable原理
    springboot2.x基础教程:@Scheduled开启定时任务及源码分析
    springboot2.x基础教程:@Async开启异步任务
    springboot2.x基础教程:JRebel实现SpringBoot热部署
  • 原文地址:https://www.cnblogs.com/lingluan23333/p/13021861.html
Copyright © 2011-2022 走看看