软件开发 102:测试

时间:2023-02-12 13:58:30

软件开发 102:测试

在我们​​之前的文章​​“软件开发 101:从程序员到软件工程师”中,我们讨论了从程序员转变为软件工程师所需的关键技能和知识。在这篇后续文章中,我们将深入探讨软件测试的主题。


我为什么要写测试?我几乎没有足够的时间。

  1. 测试使您有信心改变事物。您甚至被吓呆了要更改深奥的代码块吗?任何人都可以自信地更改经过良好测试的软件。如果更改不好,测试会让您知道。这让开发人员有信心对代码进行更改,因为他们知道测试会捕获这些更改的任何意外后果。
  2. 测试是文档。测试作为软件文档的一种形式,因为它们描述了软件应该如何运行。这对于正在处理代码的未来开发人员尤其有用。
  3. 调试变得更快更容易。测试有助于在开发过程中尽早发现缺陷和错误,以免修复起来变得更加困难和耗时。此外,他们可以将错误的搜索范围从整个程序缩小到特定功能。
  4. 改进协作。测试有助于确保软件的不同部分按预期协同工作。这在大型开发团队中尤其有用,因为它有助于确保一个开发人员所做的更改不会破坏另一个开发人员的工作。
  5. 更容易维护。随着需求的变化和代码的发展,测试有助于确保软件继续按预期运行。
  6. 测试提高了软件质量。根据我的经验,不编写测试的人认为这是编写测试的唯一好处。测试捕获代码中的错误和错误,并验证软件是否按预期运行。

对我来说,遗留代码只是没有测试的代码。


测试类型

  1. 单元测试:单元测试是一种软件测试,侧重于单独测试单个代码单元,例如函数或方法。它验证每个代码单元是否按预期运行,并有助于在开发过程的早期发现缺陷和错误。单元测试通常是自动化的,并在开发过程中频繁运行,以确保对代码的更改不会破坏现有功能。
  2. 集成测试:集成测试是一种软件测试,侧重于测试软件不同部分之间的交互。它验证软件的组件是否按预期一起工作,并有助于识别单元测试中可能不明显的问题。集成测试通常在单元测试之后执行,可以自动或手动进行。
  3. 系统测试:系统测试是一种软件测试,侧重于测试整个软件,而不是单个代码单元。它验证软件在实际场景中使用时是否按预期运行,并有助于识别性能、兼容性和整体功能方面的问题。系统测试通常在集成测试之后执行,可以自动或手动进行。
  4. 验收测试:验收测试是一种软件测试,侧重于从用户的角度测试软件。它从用户的角度验证软件的行为是否符合预期,并有助于确保软件满足用户要求。验收测试通常在系统测试之后执行,可以自动或手动进行。验收测试的目标是获得利益相关者对软件的认可并确保它已准备好发布。
import unittest


def calculate_total_cost(items, tax_rate):
# Assume this function calculates the total cost of a list of items, including tax
total = sum(item["price"] for item in items)
total += total * tax_rate
return total


def calculate_item_cost(item, tax_rate):
# Assume this function calculates the cost of a single item, including tax
cost = item["price"] * (1 + tax_rate)
return cost


def fetch_items_from_database(query):
# Assume this function fetches a list of items from a database
items = [{"name": "item1", "price": 10.0},
{"name": "item2", "price": 20.0},
{"name": "item3", "price": 30.0}]
return items


class TestUnit(unittest.TestCase):
# These unit tests check how individual functions work in isolation
def test_calculate_item_cost(self):
item = {"name": "item1", "price": 10.0}
tax_rate = 0.1
expected_cost = 11.0

result = calculate_item_cost(item, tax_rate)
self.assertAlmostEqual(result, expected_cost)

def test_calculate_total_cost(self):
items = [{"name": "item1", "price": 10.0},
{"name": "item2", "price": 20.0},
{"name": "item3", "price": 30.0}]
tax_rate = 0.1
expected_total = 66.0

result = calculate_total_cost(items, tax_rate)
self.assertAlmostEqual(result, expected_total)

def test_fetch_items_from_database(self):
query = "SELECT * FROM items"
expected_items = [{"name": "item1", "price": 10.0},
{"name": "item2", "price": 20.0},
{"name": "item3", "price": 30.0}]

result = fetch_items_from_database(query)
self.assertEqual(result, expected_items)


class TestIntegration(unittest.TestCase):
# This integration test checks how fetch_items_from_database interacts with calculate_total_cost
def test_calculate_total_cost_with_fetch_items(self):
query = "SELECT * FROM items"
items = fetch_items_from_database(query)
tax_rate = 0.1
expected_total = 66.0

result = calculate_total_cost(items, tax_rate)
self.assertAlmostEqual(result, expected_total)


class TestSystem(unittest.TestCase):
# Since our system is so small, this system test is pretty much just our integration test.
# Assume all parts of the system would be in this test case.
def test_calculate_total_cost_with_large_input(self):
items = fetch_items_from_database("SELECT * FROM items") * 1000
tax_rate = 0.1
result = calculate_total_cost(items, tax_rate)
self.assertIsNotNone(result)

def test_calculate_total_cost_with_large_tax_rate(self):
items = fetch_items_from_database("SELECT * FROM items")
tax_rate = 0.9

result = calculate_total_cost(items, tax_rate)
self.assertIsNotNone(result)


class TestAcceptance(unittest.TestCase):
# This acceptance test is supposed to test the software as a user would use it.
def test_calculate_total_cost_with_real_world_input(self):
items = fetch_items_from_database("SELECT * FROM items")
tax_rate = 0.1

result = calculate_total_cost(items, tax_rate)
self.assertAlmostEqual(result, (10.0 + 20.0 + 30.0) * (1 + tax_rate))

def test_calculate_total_cost_with_real_world_tax_rate(self):
items = fetch_items_from_database("SELECT * FROM items")
tax_rate = 0.08

result = calculate_total_cost(items, tax_rate)
self.assertAlmostEqual(result, 64.8)


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

测试驱动开发 (TDD)