白盒测试(基本路径法)代码

1 篇文章 0 订阅

白盒测试的一种常用方法是基本路径法,根据源代码构造程序流程图,转换为控制流图,得到基本路径,进而为每条基本路径设计测试用例。

基本路径法的一个关键步骤是识别出所有的基本路径。本次作业要求你写一个C++程序:

  • 输入:待测程序的控制流图
  • 输出:圈复杂度、基本路径集合

基本要求

输入:待测程序的控制流图

包含多行数据。第1行表示控制流图中的入口节点的编号,表示程序由此开始执行。后续每行代表控制流图中的一条边,表示为“1->2, T/F/N”,意即有一条边从编号为1的节点指向编号为2的节点;T表示节点1为逻辑判断节点且它为真的时候指向2;F表示节点1的条件为假的时候指向2;N表示节点1是基本语句,而不是逻辑判断节点。最后一行为“END”,表示输入结束。

例如,左侧给出的控制流图,相应的输入数据如右侧所示。

输出:圈复杂度和基本路径

输出多行数据。第一行为“CC=n”,n为一个整数,表示计算得到的圈复杂度。后续各行,每一行代表一条基本路径,格式为“1,2,3,5”的形式,逗号分隔开的是控制流图中的节点编号。

下图给出了一个示例。

注意:

  1. 在查找基本路径时,采用深度优先搜索策略;若遇到判定节点,需遵循“先遍历false分支,再遍历true分支”的原则。
  2. 若某一条路径出现循环,即:该路径的后续部分已经在本路径之前出现过,则在进入循环的第一个节点处停止,后续部分不需要再包含在该路径中(例如1,2,3,9,10,2,3这样的路径,需简化为1,2,3,9,10,2即可)。
  3. 需根据“基本路径”的定义对每一条路径进行检查,看其中是否包含了之前其他路径中不曾出现过的边。若否,则将其去除;
  4. 若程序需要输出多条基本路径,按照路径长度由小到大排序输出;若两个路径的长度相等,则按相对应位置的数字大小由低到高排列(例如1,3,6,5和1,3,4,5两条路径,后者应该先输出;1,10,8,3,4和1,9,10,3,4两条路径,后者应该先输出)。

扩展要求

作业输入中已经消除了“控制流图中的所有判断节点中包含复合条件表达式”的情形,即不存在通过and/or等逻辑运算符将多个单一条件表达式连接在一起的情况,例如 if (A and B)。

扩展:输入数据中除了边信息之外,后续增加若干新行(与原有各行之间通过一行“EXT”分隔),每一行表示控制流图中的判断节点信息,例如:

1, AND
3, OR

分别表示节点1是 if (A && B) 的形式、节点3是if (A || B)的形式。

只考虑and/or两种逻辑运算符,且只考虑包含两个单一条件表达式(A, B)的复合的情况。

为应对上述情况,你的程序应对原有控制流图进行修改,使之变为标准的控制流图的形式,再生成圈复杂度和基本路径作为输出。修改控制流图后若需要引入新的节点,其编号可采用11、12、31、32来表示。(注:原有控制流图中不会出同时出现1和11、12这样的节点,因此在对其进行修改之后,不会出现编号冲突的情况。)

以下给出了一个例子,前一个是输入,后一个为输出。


编程语言: C++ (本地运行)
编译器: g++ -m32 -D_MOODLE_ONLINE_JUDGE_ -Wall -static -o %DEST% %SOURCES% -lm
内存最多可用: 4MB
CPU使用时间上限: 5 秒

代码测试:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string>
#include<cstring>
using namespace std;
int result =0;
char sign1 = 'N';
int arcTail[100];
int arcHead[100];
int vexArr[100];

char biaodian[100]={'\0'};
int path[100]; 
string order_out = "";

typedef struct  POINT{
        int tail,head;  
        struct POINT *hlink, *tlink;    
        char biaodian; 
}POINT;

typedef struct POINT2{
        int data;
        bool visited;   
        POINT *fin, *fout;         

}POINT2;

typedef struct{
        POINT2 list[100]; 
        int vnum, anum;       
}Graph;

bool end1(string str){
     if(str == "END" || str == "end" || str == "EXT" || str == "ext")
            return true;
     return false;
}

int length(int num[]){
    int sum=0;
    for(int i=0; i<100; i++){
          if(num[i] != 0)
                sum++; 
          else
              break;
    }
    return sum;   
}

bool is_inArr(int ch[],int in){
     for(int i=0; i<length(ch); i++)
             if(in == ch[i])
                   return true;
     return false;
}



void insert(string str){
     int pos = length(vexArr);
     int i = length(arcTail);
     string _tail = str.substr(0,str.find('-'));
     string _head = str.substr(str.find('>')+1,str.find(',')-str.find('>')-1);
     char _biaodian = str[str.size()-1];
     if(!is_inArr(vexArr, atoi(_tail.c_str())))
          vexArr[pos++] = atoi(_tail.c_str());
     if(!is_inArr(vexArr, atoi(_head.c_str())))
          vexArr[pos++] = atoi(_head.c_str());
     arcTail[i] = atoi(_tail.c_str());
     arcHead[i] = atoi(_head.c_str());  
     biaodian[i] = _biaodian;         
}

int LocateVex(Graph *G, int vertex){
    int j=0,k;
    for(k=0; k<length(vexArr); k++)
             if(G->list[k].data == vertex){
                   j = k;
                   break;                   
             }    
    return j;
}

void CreateGraph(Graph *G){
     int _tail, _head;
     POINT *arcTemp;
     G->vnum = G->anum =0;
     for(int i=0; i<length(vexArr); i++){
             (*G).list[i].data = vexArr[i];
             G->list[i].fin = NULL;
             G->list[i].fout = NULL;  
             G->vnum++;  
             G->list[i].visited = false;
     }     

     //初始化弧并构建十字链表
     for(int i=0; i<length(arcTail); i++){
             if(biaodian[i] == 'T')
                     result ++;
             _tail = LocateVex(G,arcTail[i]);
             _head = LocateVex(G,arcHead[i]);
             arcTemp = (POINT*)malloc(sizeof(POINT));
             arcTemp->tail = _tail;
             arcTemp->head = _head;
             arcTemp->tlink = (*G).list[_tail].fout;
             (*G).list[_tail].fout = arcTemp;
             arcTemp->hlink = (*G).list[_head].fin;
             (*G).list[_head].fin = arcTemp;
             arcTemp->biaodian = biaodian[i]; 
             G->anum++;                       
     } 
}





void display(Graph *G,int arr[]){
     char ch[10];
     int temp =0;
     char is_no = 'N';
     for(int i=0; i<length(arr)-1; i++){
             string Arc = "";
             temp = arr[i];
             snprintf(ch,sizeof(ch),"%d",temp);
             Arc += ch;
             Arc += ",";
             temp = arr[i+1];
             snprintf(ch,sizeof(ch),"%d",temp);
             Arc += ch;
             if(order_out.find(Arc) != order_out.npos) 
                      continue;
             else{
                 is_no = 'Y';
                 break;
             } 
             i += 1;     
     }
     if(is_no == 'Y'){
              memset(ch,0,10);

     for(int i=0; i<length(arr)-1; i++){
             temp = arr[i];
             snprintf(ch,sizeof(ch),"%d",temp);
             order_out += ch;
             order_out += ",";
     }
     memset(ch,0,10);
     snprintf(ch,sizeof(ch),"%d",arr[length(arr)-1]);
     order_out += ch;
     order_out += "|"; 
     }
}

int my_memset(int arr[],int _data){
     int pos = 0;
     int _length = length(arr);
     for(int i=0; i<_length; i++)
           if(_data == arr[i]){
                     pos = i;
                     break;
           }
     for(int i=pos+1; i<_length; i++)
             arr[i] = 0;  
     //display(arr); 
     return pos;  
}
void changeVisited(Graph *G,int arr[], int num){
     char is_find_ = 'N';
     int pos =0;
     for(int i=0; i<length(arr); i++){
             if(arr[i] == num){
                       is_find_ = 'Y';
                       i++;          
             }    
             if(arr[i] != 0)
                       if(is_find_ == 'Y'){    
                                pos = LocateVex(G,arr[i]);
                                G->list[pos].visited = false;
                       }
     }     
}

//有向图的深度非递归遍历 
void DFSTraverse(Graph G, int pos){
     POINT *p;
     POINT *Queue[100*100];
     int Vex[100]={0};
     int _len_=0;
     int queue = -1;
     int pointer = -1;
     p = G.list[pos].fout;
     path[++pointer] = G.list[pos].data;
     if(!p){
           display(&G,path);
           return;
     }
     while(p){ 
           if(!is_inArr(path,G.list[p->tail].data))
                  path[++pointer] = G.list[p->tail].data;
           if(p->biaodian != 'N'){ 
                       //若遇到先前遍历过的结点则直接走F就行,T不予考虑 
                  if(is_inArr(Vex,G.list[p->tail].data) && (!G.list[p->tail].visited)){
                            if(p->biaodian == 'T')
                                        p = p->tlink;
                  }
                  else{
                       if((p->biaodian == 'T') && (!G.list[p->tail].visited)){
                             Queue[++queue] = p;
                             p = p->tlink;
                       }
                       else if(p->biaodian == 'F')
                            Queue[++queue] = p->tlink; 
                       G.list[p->tail].visited = true;
                       if(!is_inArr(Vex,G.list[p->tail].data))
                            Vex[_len_++] = G.list[p->tail].data; 
                  }
           }
           if(is_inArr(path,G.list[p->head].data)){
                  path[++pointer] = G.list[p->head].data;  
                  if(queue >= 0){ 
                                display(&G,path);         
                                p = Queue[queue];
                                queue --; 
                                pointer = my_memset(path,G.list[p->tail].data);     
                                changeVisited(&G,Vex,G.list[p->tail].data);
                  }
                  //不加else会导致死循环,因为到最后一层的时候数组为空。直接把头结点加入到循环队列中 
                  else{  
                         display(&G,path); 
                         break;
                  }
                  continue;                                            
           }
           path[++pointer] = G.list[p->head].data;
           pos = LocateVex(&G,G.list[p->head].data);
           p = G.list[pos].fout;
           if(!p){
                if(queue >= 0){     
                      display(&G,path); 
                      p = Queue[queue];
                      queue --;  
                      pointer = my_memset(path,G.list[p->tail].data);
                      changeVisited(&G,Vex,G.list[p->tail].data);
                }
                else{
                     display(&G,path);
                     break;     
                }
           }
     }
}

int returnNum(string str,char ch){
    int sum =0;
    while(str.size()){
          int pos = str.find(ch);
          if(pos != str.npos){
               str = str.substr(pos+1);
               sum++; 
          }
          else 
               break;          
    }
    return sum+1;   
}

void remove_(string str){
     int pos = order_out.find(str);
     order_out.replace(pos,str.size()+1,"");     
}

bool my_compare(string str1,string str2){
     str1 += ",";
     str2 += ",";
     string temp1 = "";
     string temp2 = "";
     int pos1 = str1.find(',');
     int pos2 = str2.find(',');
     while(str1.size()){
              temp1 = str1.substr(0,pos1);
              temp2 = str2.substr(0,pos2);
              if(atoi(temp1.c_str()) > atoi(temp2.c_str()))
				  return true;  
              else if(atoi(temp1.c_str()) < atoi(temp2.c_str()))
                  return false;
              str1 = str1.substr(pos1+1);
              pos1 = str1.find(',');
              str2 = str2.substr(pos2+1);  
              pos2 = str2.find(',');                
     }     
}

void orderDisplay(string str){
     string ordered = "";
     string _str = str;
     string small = str;
     int small_num = 100;
     string temp = "";
     char end1 = 'N';
     int pos = str.find('|');
     while(str.size()){
     for(int i=0; i<_str.size(); i++){
           temp = _str.substr(0,pos);
           if(returnNum(temp,',') < small_num){
                        small = temp;
                        small_num = returnNum(temp,',');
           }
           else if(returnNum(temp,',') == small_num)
                 if(my_compare(small,temp)){
                              small = temp; 
                              small_num = returnNum(temp,',');
                 }
           if(end1 == 'N'){
                _str = _str.substr(pos+1);  
                pos = _str.find('|');
                if(pos != _str.npos)
                     continue;
                else{
                     pos = _str.size();
                     end1 = 'Y';     
                }
           } 
           else
               break;   
     }
     ordered += small;
     ordered += "|";
     int _pos = str.find(small);
     str.replace(_pos,small.size()+1,"");
     _str = small = str;
     small_num =100;
     pos = str.find('|');
     end1 = 'N';
     }     
     order_out = ordered;  
}

void coutResult(string str){
     int pos = str.find('|');
     string temp;
     while(str.size()){
              temp = str.substr(0,pos);
              cout << temp << endl;
              str = str.substr(pos+1);
              pos = str.find('|');                  
     }
}

void changeVexArr(int num){
     for(int i=0; i<length(vexArr); i++)
             if(vexArr[i] == num){
                   vexArr[i] = num*10 + 1;
                   vexArr[length(vexArr)] = num*10 + 2;
                   break;             
             }             
}

void CreatePath(string str){
     string _vertex = str.substr(0,str.find(','));
     string _condition = str.substr(str.find(',')+1);
     int _num = atoi(_vertex.c_str());
     int _T = 0,_F = 0,_in[100]={0};
     int l = length(arcTail);
     int l_l =0;
     changeVexArr(_num);  
     for(int i=0; i<l; i++)
                   if(arcHead[i] == _num)
                          _in[l_l++] = i;                    
     for(int j=0; j<l; j++){
                   if((biaodian[j] == 'F') && (arcTail[j] == _num))
                        _F = j;
                   else if((biaodian[j] == 'T') && (arcTail[j] == _num)) 
                        _T = j;                            
     }
     for(int i=0; i<l_l; i++)
                   arcHead[_in[i]] = _num*10+1;
     if(_condition == "AND"){   
           int _into = length(arcTail);
           arcTail[_F] = _num*10+1;   
           arcTail[_into] = _num*10+1;   
           arcHead[_into] = _num*10+2;
           biaodian[_into] = 'T';
           _into ++;
           arcTail[_T] = _num*10+2;
           arcTail[_into] = _num*10+2;
           arcHead[_into] = arcHead[_F];
           biaodian[_into] = 'F';
     }

     else if(_condition == "OR"){

           int _into = length(arcTail);
           arcTail[_T] = _num*10+1;
           arcTail[_into] = _num*10+1;
           arcHead[_into] = _num*10+2;
           biaodian[_into] = 'F';
           _into++;
           arcTail[_F] = _num*10+2;
           arcTail[_into] = _num*10+2;
           arcHead[_into] = arcHead[_T];
           biaodian[_into] = 'T';
     }
}
/*
void xianshi(){
    for(int i=0; i<length(vexArr); i++)
            cout << vexArr[i] << endl;
    for(int i=0; i<length(arcTail); i++)
            cout << arcTail[i] << "->" << arcHead[i] << "," << biaodian[i] << endl;     
}
*/
int main(){
    Graph G;
    int i=0;
    string temp ="";
	memset(arcTail,0,sizeof(arcTail));
	memset(arcTail,0,sizeof(arcHead));
	
	memset(arcTail,0,sizeof(vexArr));
    int _header = 0;
    getline(cin,temp);

    if(temp == "END")
            return 0;
    vexArr[i++] = atoi(temp.c_str());
    while(1){
             getline(cin,temp);
             if(temp == "EXT" || temp == "ext")
                   sign1 = 'Y';
             if(end1(temp)) 
                   break;
             insert(temp);        
    }
    if(sign1 == 'Y')
             while(1){
                      getline(cin,temp);
                      if(end1(temp))
                            break;
                      CreatePath(temp); 
             }
    CreateGraph(&G);
    DFSTraverse(G,LocateVex(&G,vexArr[0]));
    cout << "CC=" << returnNum(order_out,'|')-1 << endl;
    for(int i=0;i<10;i++)
    orderDisplay(order_out);
    coutResult(order_out);
	//while(1)
		//getchar();
    return 0;   
}


  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值