Python测试线程应用程序

在本章中,我们将学习线程应用程序的测试。我们还将了解测试的重要性。

为什么要测试?

在我们深入讨论测试的重要性之前,我们需要知道测试的内容。一般来说,测试是一种了解某些东西是如何运作的技术。另一方面,特别是如果我们谈论计算机程序或软件,那么测试就是访问软件程序功能的技术。

在本节中,我们将讨论软件测试的重要性。在软件开发中,必须在向客户端发布软件之前进行双重检查。这就是由经验丰富的测试团队测试软件非常重要的原因。请考虑以下几点来理解软件测试的重要性

提高软件质量

当然,没有公司想要提供低质量的软件,也没有客户想购买低质量的软件。测试通过查找和修复其中的错误来提高软件的质量。

客户满意度

任何业务中最重要的部分是客户的满意度。通过提供无错误和优质软件,公司可以实现客户满意度。

减轻新功能的影响

假设我们已经建立了一个10000行的软件系统,我们需要添加一个新功能,然后开发团队就会担心这个新功能对整个软件的影响。此外,测试也起着至关重要的作用,因为如果测试团队已经完成了一系列测试,那么它可以使我们免于任何潜在的灾难性中断。

用户体验

任何业务中另一个最重要的部分是该产品用户的体验。只有测试可以确保最终用户发现它简单易用。

减少开支

测试可以通过在开发的测试阶段找到并修复错误而不是在交付后修复它来降低软件的总成本。如果在交付软件后出现重大错误,那么就客户不满意,公司负面声誉等方面的费用和无形成本而言,会增加其实际成本。

测试什么?

始终建议您对要测试的内容有适当的了解。在本节中,我们将首先了解测试任何软件时测试人员的主要动机。代码覆盖率,即我们的测试套件在测试时会遇到多少行代码,应该避免。这是因为,在测试时,仅关注代码行数对我们的系统没有任何实际价值。可能仍然存在一些错误,即使在部署之后,这些错误也会在稍后阶段反映出来。

考虑以下与测试内容相关的重要观点

  • 我们需要专注于测试代码的功能而不是代码覆盖率。
  • 我们需要首先测试代码中最重要的部分,然后转向代码中不太重要的部分。这肯定会节省时间。
  • 测试人员必须具有多种不同的测试,可以将软件推向极限。

测试并发软件程序的方法

由于能够利用多核架构的真正能力,并发软件系统正在取代顺序系统。最近,并发系统程序被用于从手机到洗衣机,从汽车到飞机等各种各样的系统程序。我们需要更加谨慎地测试并发软件程序,因为如果我们已经为单线程应用程序添加了多个线程已经是一个错误,那么我们最终会遇到多个错误。

并发软件程序的测试技术广泛关注于选择交错,这种交错暴露了可能有害的模式,如竞争条件,死锁和违反原子性。以下是测试并发软件程序的两种方法

系统探索

该方法旨在尽可能广泛地探索交错的空间。这种方法可以采用蛮力技术,其他方法采用偏序降阶技术或启发式技术来探索交织空间。

房产驱动

属性驱动的方法依赖于观察到并发错误更可能发生在暴露特定属性(例如可疑内存访问模式)的交错下。不同的属性驱动方法针对不同的错误,如竞争条件,死锁和违反原子性,这进一步取决于一个或其他特定属性。

测试策略

测试策略也称为测试方法。该策略定义了如何进行测试。测试方法有两种技术 -

主动

一种方法,尽可能早地启动测试设计过程,以便在创建构建之前找到并修复缺陷。

反应

一种方法,在开发过程完成之前,测试不会开始。

在对python程序应用任何测试策略或方法之前,我们必须对软件程序可能具有的错误类型有一个基本的想法。错误如下

语法错误

在程序开发期间,可能会出现许多小错误。错误主要是由于输入错误。例如,缺少冒号或关键字的拼写错误等。此类错误是由于程序语法错误而非逻辑错误造成的。因此,这些错误称为语法错误。

语义错误

语义错误也称为逻辑错误。如果软件程序中存在逻辑或语义错误,则语句将正确编译并运行,但由于逻辑不正确,因此无法提供所需的输出。

单元测试

这是测试python程序最常用的测试策略之一。此策略用于测试代码的单元或组件。按单位或组件,我们指的是代码的类或函数。单元测试通过测试“小”单元简化了大型编程系统的测试。借助于上述概念,单元测试可以被定义为一种方法,其中测试各个源代码单元以确定它们是否返回所需的输出。

在随后的章节中,我们将了解用于单元测试的不同Python模块。

unittest模块

单元测试的第一个模块是unittest模块。它受JUnit的启发,默认情况下包含在Python3.6中。它支持测试自动化,共享测试的设置和关闭代码,将测试聚合到集合中,以及测试与报告框架的独立性。

以下是unittest模块支持的一些重要概念

文字夹具

它用于设置测试,以便在开始测试之前运行并在测试结束后拆除。它可能涉及在开始测试之前创建临时数据库,目录等。

测试用例

测试用例检查所需的响应是否来自特定的输入集。unittest模块包含一个名为TestCase的基类,可用于创建新的测试用例。它包含两个默认方法 -

  • setUp() - 一种用于在运行之前设置测试夹具的钩子方法。 在调用实现的测试方法之前调用它。
  • tearDown( - 用于在类中运行所有测试后解构类夹具的钩子方法。

测试套件

它是测试套件,测试用例或两者的集合。

试验跑步者

它控制测试用例或套装的运行,并为用户提供结果。它可以使用GUI或简单的文本界面来提供结果。

以下Python程序使用unittest模块来测试名为 Fibonacci
的模块。该程序有助于计算一个数字的斐波那契数列。在此示例中,我们创建了一个名为Fibo_test的类,以使用不同的方法定义测试用例。这些方法继承自unittest.TestCase。我们使用两种默认方法 setUp()和tearDown()。我们还定义了testfibocal方法。必须使用字母测试开始测试的名称。在最后一个块中,unittest.main()为测试脚本提供了一个命令行界面。

import unittest
def fibonacci(n):
   a, b = 0, 1
   for i in range(n):
   a, b = b, a + b
   return a
class Fibo_Test(unittest.TestCase):
   def setUp(self):
   print("This is run before our tests would be executed")
   def tearDown(self):
   print("This is run after the completion of execution of our tests")

   def testfibocal(self):
   self.assertEqual(fib(0), 0)
   self.assertEqual(fib(1), 1)
   self.assertEqual(fib(5), 5)
   self.assertEqual(fib(10), 55)
   self.assertEqual(fib(20), 6765)

if __name__ == "__main__":
   unittest.main()

从命令行运行时,上面的脚本会生成一个如下所示的输出 -

输出

This runs before our tests would be executed.
This runs after the completion of execution of our tests.
.
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK

现在,为了更清楚,我们正在改变我们的代码,这有助于定义Fibonacci模块。

以下面的代码块为例

def fibonacci(n):
   a, b = 0, 1
   for i in range(n):
   a, b = b, a + b
   return a

对代码块进行了一些更改,如下所示 -

def fibonacci(n):
   a, b = 1, 1
   for i in range(n):
   a, b = b, a + b
   return a

现在,在使用更改的代码运行脚本后,我们将获得以下输出

This runs before our tests would be executed.
This runs after the completion of execution of our tests.
F
======================================================================
FAIL: testCalculation (__main__.Fibo_Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "unitg.py", line 15, in testCalculation
self.assertEqual(fib(0), 0)
AssertionError: 1 != 0
----------------------------------------------------------------------
Ran 1 test in 0.007s

FAILED (failures = 1)

上面的输出显示模块未能提供所需的输出。

Docktest模块

docktest模块还有助于单元测试。它还预先包装了python。它比unittest模块更容易使用。unittest模块更适合复杂的测试。要使用doctest模块,我们需要导入它。相应函数的docstring必须具有交互式python会话及其输出。

如果我们的代码中的一切都很好,那么docktest模块就没有输出; 否则,它将提供输出。

以下Python示例使用docktest模块测试名为Fibonacci的模块,该模块有助于计算数字的Fibonacci系列。

import doctest
def fibonacci(n):
   """
   Calculates the Fibonacci number

   >>> fibonacci(0)
   0
   >>> fibonacci(1)
   1
   >>> fibonacci(10)
   55
   >>> fibonacci(20)
   6765
   >>>

   """
   a, b = 1, 1
   for i in range(n):
   a, b = b, a + b
   return a
      if __name__ == "__main__":
   doctest.testmod()

我们可以看到名为fib的相应函数的docstring具有交互式python会话以及输出。如果我们的代码没问题,那么doctest模块就没有输出。但要了解它是如何工作的,我们可以使用-v选项运行它。

(base) D:\ProgramData>python dock_test.py -v
Trying:
   fibonacci(0)
Expecting:
   0
ok
Trying:
   fibonacci(1)
Expecting:
   1
ok
Trying:
   fibonacci(10)
Expecting:
   55
ok
Trying:
   fibonacci(20)
Expecting:
   6765
ok
1 items had no tests:
   __main__
1 items passed all tests:
4 tests in __main__.fibonacci
4 tests in 2 items.
4 passed and 0 failed.
Test passed.

现在,我们将更改有助于定义Fibonacci模块的代码

以下面的代码块为例

def fibonacci(n):
   a, b = 0, 1
   for i in range(n):
   a, b = b, a + b
   return a

以下代码块有助于更改

def fibonacci(n):
   a, b = 1, 1
   for i in range(n):
   a, b = b, a + b
   return a

在没有-v选项的情况下运行脚本后,使用更改的代码,我们将获得如下所示的输出。

输出

(base) D:\ProgramData>python dock_test.py
**********************************************************************
File "unitg.py", line 6, in __main__.fibonacci
Failed example:
   fibonacci(0)
Expected:
   0
Got:
   1
**********************************************************************
File "unitg.py", line 10, in __main__.fibonacci
Failed example:
   fibonacci(10)
Expected:
   55
Got:
   89
**********************************************************************
File "unitg.py", line 12, in __main__.fibonacci
Failed example:
   fibonacci(20)
Expected:
   6765
Got:
   10946
**********************************************************************
1 items had failures:
   3 of 4 in __main__.fibonacci
***Test Failed*** 3 failures.

我们可以在上面的输出中看到三个测试都失败了。
本文转自:http://codingdict.com/article/8871

原文地址:https://www.cnblogs.com/bczd/p/12119275.html

时间: 2024-10-07 18:33:22

Python测试线程应用程序的相关文章

聊一下Python的线程 & GIL

再来聊一下Python的线程 参考这篇文章 https://www.zhihu.com/question/23474039/answer/24695447 简单地说就是作为可能是仅有的支持多线程的解释型语言(perl的多线程是残疾,PHP没有多线程),Python的多线程是有compromise的,在任意时间只有一个Python解释器在解释Python bytecode.Ruby也是有thread支持的,而且至少Ruby MRI是有GIL的. 首先要了解 GIL,全称 Global Interp

Python:线程、进程与协程(1)——概念

最近的业余时间主要放在了学习Python线程.进程和协程里,第一次用python的多线程和多进程是在两个月前,当时只是简单的看了几篇博文然后就跟着用,没有仔细去研究,第一次用的感觉它们其实挺简单的,最近这段时间通过看书, 看Python 中文官方文档等等相关资料,发现并没有想想中的那么简单,很多知识点需要仔细去理解,Python线程.进程和协程应该是Python的高级用法.Python的高级用法有很多,看看Python 中文官方文档就知道了,当然有时间看看这些模块是怎么实现的对自己的提高是很有帮

在python中单线程,多线程,多进程对CPU的利用率实测以及GIL原理分析

首先关于在python中单线程,多线程,多进程对cpu的利用率实测如下: 单线程,多线程,多进程测试代码使用死循环. 1)单线程: 2)多线程: 3)多进程: 查看cpu使用效率: 开始观察分别执行时候cpu的使用效率: 1)单线程执行的时候: 2)多线程执行的时候: 3)多进程执行的时候: 总结: 1)单进程单线程时,对于双核CPU的利用率只能利用一个核,没有充分利用两个核. 2)单进程多线程时,对于双核CPU的来说,虽然两个核都用到的,不过很明显没有充分利用两个核,这里要说一个GIL(全局解

Python基础—线程、进程和协程

今天已是学习Python的第十一天,来干一碗鸡汤继续今天的内容,今天的鸡汤是:超越别人对你的期望.本篇博客主要介绍以下几点内容: 线程的基本使用: 线程的锁机制: 生产者消费之模型(队列): 如何自定义线程池: 进程的基本使用: 进程的锁机制: 进程之间如何实现数据共享: 进程池: 协程的基本使用. 一.线程 1.创建线程 上篇博客已经介绍过如何创建多线程的程序,在这里在复习一下如何创建线程过程以及线程的一些方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1

使用Python实现Hadoop MapReduce程序

转自:使用Python实现Hadoop MapReduce程序 英文原文:Writing an Hadoop MapReduce Program in Python 根据上面两篇文章,下面是我在自己的ubuntu上的运行过程.文字基本采用博文使用Python实现Hadoop MapReduce程序,  打字很浪费时间滴. 在这个实例中,我将会向大家介绍如何使用Python 为 Hadoop编写一个简单的MapReduce程序. 尽管Hadoop 框架是使用Java编写的但是我们仍然需要使用像C+

Python:线程、进程与协程(4)——multiprocessing模块(1)

multiprocessing模块是Python提供的用于多进程开发的包,multiprocessing包提供本地和远程两种并发,通过使用子进程而非线程有效地回避了全局解释器锁. (一)创建进程Process 类 创建进程的类,其源码在multiprocessing包的process.py里,有兴趣的可以对照着源码边理解边学习.它的用法同threading.Thread差不多,从它的类定义上就可以看的出来,如下: class Process(object):     '''     Proces

Python重写C语言程序100例--Part10

软中断 软中断的分配时静态的(即在编译时定义),而tasklet的分配和初始化可以在运行时进行. 软中断(即便是同一种类型的软中断)可以并发地运行在多个CPU上.因此,软中断是可重入函数而且必须明确地使用自旋锁保护其数据结构.tasklet不必担心这些问题,因为内核对tasklet的执行进行了更加严格的控制.相同类型的tasklet总是被串行执行. 换句话说就是:不能在两个CPU上同时运行相同类型的tasklet.但是,类型不同的tasklet可以在几个CPU上并发执行.tasklet的串行化使

Python之线程与GIL

前言            以下内容是个人学习之后的感悟,转载请注明出处~ 线程是什么 线程是程序中一个单一的顺序控制流程.进程内一个相对独立的.可调度的执行单元,是系统独立调度和分派CPU的 基本单位指运行中的程序的调度单位.在单个程序中同时运行多个线程完成不同的工作,称为多线程. GIL是什么 为了更有效的利用多核处理器的性能,就出现了多线程的编程方式,Python当然也逃不开,为了利用多核,Python开 始支持多线程.而解决多线程之间数据完整性和状态同步的最简单方法自然就是加锁. 于是有

python之线程、进程和协程

引言 解释器环境:python3.5.1我们都知道python网络编程的两大必学模块socket和socketserver,其中的socketserver是一个支持IO多路复用和多线程.多进程的模块.一般我们在socketserver服务端代码中都会写这么一句:server = socketserver.ThreadingTCPServer(settings.IP_PORT, MyServer)ThreadingTCPServer这个类是一个支持多线程和TCP协议的socketserver,它的