软件测试课程设计——tcas的测试脚本(续)

文章目录

  • 参考博客
  • 具体改进
  • Correct
    • 1. 可执行语句数量
    • 最终代码地址
    • 2.统计矩阵时少收集一行数据
  • Remind
  • Tips:
    • Q1
    • Q2
    • Q3
    • Q4

参考博客

首先依旧是参考
SIR的tcas项目:https://sir.csc.ncsu.edu/php/common/download.php?ac=pub&key=sir/cobjects/sun&id=20&file=tcas_2.0.tar.gz
介绍tcas:https://blog.csdn.net/mangoer_ys/article/details/25974067
介绍gcov工具:https://blog.csdn.net/yanxiangyfg/article/details/80989680
前文:https://blog.csdn.net/CAceAs/article/details/88834485

具体改进

按照昨天的反思,我尝试移除了lcov语句,这样就没有简洁的info文档可供读取,仅能读取tcas.c.gcov。

提升有三:
1.运行速度大大提升,在虚拟机的linux系统运行一个版本的时间由约240秒到18秒。
2.除了需要的matrix和result外不生成过多的多余文档(之前每个版本下有1608个t1,t2…记录分支覆盖和r1,r2…记录lcov结果)
3.因为效率提高,所以一次运行了41个版本。之前需手动改变version40次
以下是具体代码:

import os
import numpy as np
version = 1
test = 1
statement = 1

f = open("./runall.sh")
oldscript = f.readlines()

for version in range(1,42):
	#version
	#this module is used for running test language----shell
	matrix = np.zeros((1609,65))
	os.system("gcc -fprofile-arcs -ftest-coverage -o ../versions.alt/versions.orig/v"+str(version)+"/tcas.exe ../versions.alt/versions.orig/v"+str(version)+"/tcas.c -w\n")
	os.system("cp ../versions.alt/versions.orig/v"+str(version)+"/tcas.exe ../source\n")
	os.system("mv ../scripts/tcas.gcno ../versions.alt/versions.orig/v"+str(version)+"\n")
	os.system("mkdir ../outputs/v"+str(version)+"\n")
	oldscript = [line for line in oldscript if(not line.startswith("echo"))]
	for line in oldscript:
		#test case
		os.system(line.replace('../outputs', '../outputs/v'+str(version)))
		os.system("mv ../scripts/tcas.gcda ../versions.alt/versions.orig/v"+str(version)+"\n")
		os.system("gcov -b ../versions.alt/versions.orig/v"+str(version)+"/tcas.c > /dev/null")
		g = open("tcas.c.gcov")
		#this module is used for generate test case matrix
		for line in g.readlines():
			#statement
			if(line.strip()[0] in ('1','2','3','4','5','6','7','8')):
				matrix[test-1][statement-1] = int(line.strip()[0])
				matrix[-1][statement-1] += 1
				statement += 1
			elif(line.strip()[0] == '#'):
				matrix[test-1][statement-1] = 0
				statement += 1
		statement = 1
		test += 1
		g.close()
	test = 1
	np.savetxt("../versions.alt/versions.orig/v"+str(version)+"/matrix",matrix,fmt='%d')
	#this module is used for print out results
	false_num = 0
	true_num = 0
	LF = 65
	LH = 0
	max_num = 0
	min_num = 1608
	sum_num = 0
	mean_num = 0
	for i in range(1, 1609):
		tmp = os.system("diff ../outputs/v0/t"+str(i)+" ../outputs/v"+str(version)+"/t" + str(i) + ">/dev/null")
		if tmp != 0:
			false_num += 1
		else:
			true_num += 1
	for i in range(0,LF):
		if(matrix[-1][i-1] != 0):
			LH += 1	
		if(matrix[-1][i-1] > max_num):
			max_num = matrix[-1][i-1]
		if(matrix[-1][i-1] < min_num):
			min_num = matrix[-1][i-1]
		sum_num += matrix[-1][i-1]
	linecov = round(LH/LF,4)
	mean_num = round(sum_num/LF,2)
	r = open("../versions.alt/versions.orig/v"+str(version)+"/result","w+")
	r.write("True test number: "+str(true_num)+"\nFalse test number: "+str(false_num))
	r.write("\nThe total statements: "+str(LF)+"\nThe statements executed: "+str(LH))
	r.write("\nThe line coverage: "+("%.2f%%" % (linecov * 100)))
	r.write("\nMax number of executed times: "+str(max_num))
	r.write("\nMin number of executed times: "+str(min_num))
	r.write("\nMean number of execute times: "+str(mean_num))
	r.close()
f.close()

其中,

oldscript = [line for line in oldscript if(not line.startswith("echo"))]

是一个对line的判断,仅读取测试用例进入oldscript,取代了添加一个额外的if判断,减少一层代码上的嵌套。

for line in g.readlines():
			#statement
			if(line.strip()[0] in ('1','2','3','4','5','6','7','8')):
				matrix[test-1][statement-1] = int(line.strip()[0])
				matrix[-1][statement-1] += 1
				statement += 1
			elif(line.strip()[0] == '#'):
				matrix[test-1][statement-1] = 0
				statement += 1

改进的核心,读取gcov文件部分,将数字开头的文件读入matrix,由于未被执行的可执行语句并不是用‘0’而是‘#####’表示,所以分两个判断读取,将之前版本的matrix最后一行的生成循环即:

for cursor in range(0,65):
	for test_num in range(0,1608):
		if(matrix[test_num][cursor] != 0):
			matrix[-1][cursor] = matrix[-1][cursor] + 1

合并到这一循环中。

Correct

1. 可执行语句数量

在优化之后尝试运行了41个版本,发现了一处问题,编译报错大概是:Index 65 is out of matrix,出错代码是

				matrix[test-1][statement-1] = int(line.strip()[0])

原因:在程序中定义matrix时采用np.zeros((1609,65)),其中65意味着我们默认可执行语句是65个,这也是下面没计算LF的原因,但是具体定位发现,第31个版本是67个可执行语句,导致矩阵索引超过边界。

最终代码地址

因此,给出最后的修改好的测试脚本:
如果觉得有用请Star一下哦!

有很多细微改动,主要解决办法是
1.在进行第一层循环(版本级别)时加上LF=0
2.定义matrix有100列
3.在结束第三层循环(语句级别)后,清空statement之前将值赋给LF
4.savetxt时保存内容由matrix改成matrix[:,0:LF]

2.统计矩阵时少收集一行数据

在进行第一处纠错后发现第二个问题,LH(被执行语句)总是少一个,平均值也总是偏小,那么原因在哪儿呢?对比发现在对写好的矩阵进行统计时好像总是少收集一行数据,出错代码在:

for i in range(0,LF):
		if(matrix[-1][i-1] != 0):
			LH += 1	
		if(matrix[-1][i-1] > max_num):
			max_num = matrix[-1][i-1]
		if(matrix[-1][i-1] < min_num):
			min_num = matrix[-1][i-1]
		sum_num += matrix[-1][i-1]

i的取值范围在0,LF就是执行到LF-1这没有错,但是下文就不应该再按照[i-1]进行取值,因为0,LF已经考虑了索引值从0开始的事实。只要把i-1改为i就行。
但是更深入的考虑一下,为什么之前就没有错误呢?改变LF不能改变i-1写错了的事实啊,为什么之前数据都正确呢?
原因是!当时矩阵定义了65列,没有一行是多余数据,以i-1为索引时读取按照-1,0,1,2…63进行统计,而矩阵的-1索引代表倒数第一列,正好统计了64,巧合般的完全覆盖了,而改正后统计矩阵为zeros((1609,100))倒数第一列显然不会存放有效数据,问题就暴露了。

Remind

这次改进仍给我带来新理解,这次的版本显然更简洁高效,但是与之前版本按步骤给出代码相比,这次的代码可读性可能变差了。尽管我认为还是更优雅了一些

Tips:

Q1

编译报错:TypeError: ‘builtin_function_or_method’ object has no attribute ‘getitem
以及
编译报错:TypeError: ‘builtin_function_or_method’ object is not iterable
原因:使用readlines未添加括号。

Q2

编译报错:inconsistent use of tabs and spaces in indentation
原因:在缩进中不一致地使用Tab和空格,所以python需要很严格的格式,对齐很重要.
解决:重新敲缩进

Q3

使用gc编译器命令时弹出编译警告,不影响运行但是打乱命令行的观察
解决:gcc命令最后加上参数-w(-Wall)

Q4

使用mkdir命令弹出文件夹已存在的警告,不影响运行但是打乱命令行的观察
解决:加上-p参数

你可能感兴趣的:(软件测试课程设计——tcas的测试脚本(续))