为python代码自动生成单元测试

auger-python的Python项目详细描述


螺旋钻

auger是一个为python代码自动生成单元测试的项目。

these slidesthis blog 更多信息请登录。

安装

使用以下部件安装螺旋输送器:

pip install auger-python

运转螺旋输送器

要为python 2或3的任何类或模块生成单元测试,请执行以下操作:

import auger

with auger.magic([ <any list of modules or classes> ]):
    <any code that exercises your application>

一个简单的例子

下面是一个完全不依赖螺旋钻的简单示例:

class Foo:                # Declare a class with a method
    def bar(self, x):
        return 2 * x .    # Duplicate x and return it

def main():
    foo = Foo()           # Create an instance of Foo
    print(foo.bar(32))    # Call the bar method and print the result

main()

main函数中,我们调用bar方法,它将打印64。

在我们的简单示例中运行螺旋钻

为了生成这个类的单元测试,我们再次运行代码,但这次是在auger的上下文中:

import auger

with auger.magic([Foo]):
    main()

这将打印以下内容:

64
Auger: generated test: tests/test_Foo.py

生成的测试如下所示,删除了一些main的导入和测试:

import unittest

class FooTest(unittest.TestCase):
    def test_bar(self):
        foo_instance = Foo()
        self.assertEquals(
            foo_instance.bar(x=32),
            64
        )

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

在详细模式下运行螺旋输送器

除了在文件系统中发出测试,auger还可以将测试打印到控制台, 通过使用verbose参数:

import auger

with auger.magic([Foo], verbose=True):
    main()

在这种情况下,螺旋钻不会生成任何测试,而只是打印出来。

更大的示例

考虑下面的例子,pet.py,包含在sample文件夹中,它允许我们创建一个Pet,其中包含一个名称和一个种类:

from animal import Animal

class Pet(Animal):
  def __init__(self, name, species):
    Animal.__init__(self, species)
    self.name = name

  def getName(self):
    return self.name

  def __str__(self):
    return "%s is a %s" % (self.getName(), self.getSpecies())

def createPet(name, species):
  return Pet(name, species)

一个Pet实际上是一种特殊的Animal,它有一个名字,定义在animal.py

class Animal(object):
  def __init__(self, species):
    self.species = species

  def getSpecies(self):
    return self.species

有了这两个定义,我们可以创建一个Pet实例并打印出一些详细信息:

import animal
import pet

def main():
  p = pet.createPet("Polly", "Parrot")
  print(p, p.getName(), p.getSpecies())

main()      

这将产生:

Polly is a Parrot Polly Parrot

在更大的示例中调用螺旋输送器

使用auger,我们可以记录对pet.py中定义的所有函数和方法的所有调用, 同时还要记住从pet.py到其他模块的所有调用的详细信息, 所以他们可以被嘲笑。

而不是说:

if __name__ == "__main__":
  main()

我们会说:

import auger

if __name__ == "__main__":
  with auger.magic([pet]):   # this is the new line and invokes Auger
    main()

这将为pet.py生成以下自动生成的单元测试:

from mock import patch
from sample.animal import Animal
import sample.pet
from sample.pet import Pet
import unittest


class PetTest(unittest.TestCase):
    @patch.object(Animal, 'get_species')
    @patch.object(Animal, 'get_age')
    def test___str__(self, mock_get_age, mock_get_species):
        mock_get_age.return_value = 12
        mock_get_species.return_value = 'Dog'
        pet_instance = Pet('Clifford', 'Dog', 12)
        self.assertEquals(pet_instance.__str__(), 'Clifford is a dog aged 12')

    def test_create_pet(self):
        self.assertIsInstance(sample.pet.create_pet(age=12,species='Dog',name='Clifford'), Pet)

    def test_get_name(self):
        pet_instance = Pet('Clifford', 'Dog', 12)
        self.assertEquals(pet_instance.get_name(), 'Clifford')

    def test_lower(self):
        self.assertEquals(Pet.lower(s='Dog'), 'dog')

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

注意,auger检测对象创建、方法调用和静态方法。它是自动的 为Animal生成模拟。模拟get_species返回“dog”,而get_age返回12。 也就是说,这些是我们上次运行示例代码时auger记录的值。

螺旋钻的优点

通过自动生成单元测试,我们大大降低了软件成本 发展。测试本身旨在帮助开发人员进行单元测试 并降低如何编写测试的学习曲线。

螺旋钻的已知限制

auger不尝试用合成值(如-1None[])替换参数。 当代码使用异常时,auger也不能很好地工作。auger也不喜欢有decorator的方法。

auger只记录给定的执行运行并将运行保存为测试。俄歇不知道代码是否真的 按预期工作。如果代码包含一个bug,auger将简单地记录bug行为。没有免费的 在这里吃午饭。由开发人员来验证代码是否有效。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java find安全漏洞不扫描groovy文件   java有没有办法将Jacoco设置为IntelliJ中的默认代码覆盖工具?   有人能帮我吗?我没有得到输出   java从另一个子类中不可用的超类调用子类方法   带undertow servlet容器的springboot应用程序中出现java“无通用密码套件”错误   java Listview:无法解析符号“setAdapter”   PostgreSQL行更改通知java程序,反之亦然   用于密码验证的java正则表达式第一个和最后一个字母不能有符号   java通过SNMP4J连接两台计算机   java如何使用sqlite部署javafx应用程序?   如何修复javax。邮政通过GMail使用SMTP时的MessaginException?   Selenium弹出窗口的java问题   Java主教棋盘算法   当抛出异常时,返回CompletableFuture的java方法执行两次