单元测试框架

合集下载

单元测试框架Unittest

单元测试框架Unittest

单元测试框架Unittest Unittest官⽅ 4个重要概念:Test fixture(测试固件):初始化、清除Test case(测试⽤例),test suite(测试套件),test runner(测试运⾏器)两种单元测试加载⽅法:1.unittest.main()2.将所有test case 添加到test suit中,然后⼀次性加载知识点:1.测试类要继承unittest.TestCase类2.每个⽤例⽅法 test开头(self)3.setUp和tearDown⽅法在每个⽤例执⾏前后都会执⾏4.unittest.main()执⾏同⼀模块内unittest⼦类所有⽅法实例被测试模块 Calc.py后续部分⽤例会引⽤此模块1# coding=utf-82class Calc(object):3def add(self, x, y, *d):4# 加法计算5 result = x + y6for i in d:7 result += i8return result910def sub(self, x, y, *d):11# 减法计算12 result = x - y13for i in d:14 result -= i15return result1617 @classmethod18def mul(cls, x, y, *d):19# 乘法计算20 result = x * y21for i in d:22 result *= i23return result2425 @staticmethod26def div(x, y, *d):27# 除法计算28if y != 0:29 result = x / y30else:31return -132for i in d:33if i != 0:34 result /= i35else:36return -137return result例⼦1 ⽤例初始化清除setUp、tearDown1#encoding=utf-82import unittest3import random4class TestSequenceFunctions(unittest.TestCase):5def setUp(self):6# 初始化⼀个递增序列7 self.seq = range(10)8print"setup completed!"910def test_run(self):11# 从序列seq中随机选取⼀个元素12 element = random.choice(self.seq)13# 验证随机元素确实属于列表中14 self.assertTrue(element in self.seq)1516def test_sth(self):17assert 1==11819def tearDown(self):20print"tearDown completed"2122class TestDictValueFormatFunctions(unittest.TestCase):23def setUp(self):24 self.seq = range(10)2526def test_shuffle(self):27# 随机打乱原seq的顺序28 random.shuffle(self.seq)29 self.seq.sort()30 self.assertEqual(self.seq, range(10))31# 验证执⾏函数时抛出了TypeError异常32 self.assertRaises(TypeError, random.shuffle, (1, 2, 3))3334if__name__ == '__main__':35 unittest.main()例⼦2 类初始化清除setUpClass(cls)、tearDownClass(cls)类⾥所有⽤例执⾏前后仅执⾏⼀次1#encoding=utf-82import unittest34# 被测试类5class myclass(object):6 @classmethod7def sum(self, a, b):8return a + b #将两个传⼊参数进⾏相加操作910 @classmethod11def sub(self, a, b):12return a - b #将两个传⼊参数进⾏相减操作131415class mytest(unittest.TestCase):16 @classmethod17def setUpClass(cls):18"初始化类固件"19print"----setUpClass"2021 @classmethod22def tearDownClass(cls):23"重构类固件"24print"----tearDownClass"2526# 初始化⼯作27def setUp(self):28 self.a = 329 self.b = 130print"--setUp"3132# 退出清理⼯作33def tearDown(self):34print"--tearDown"3536# 具体的测试⽤例,⼀定要以test开头37def testsum(self):38# 断⾔两数之和的结果是否是439 self.assertEqual(myclass.sum(self.a, self.b), 4, 'test sum fail')4041def testsub(self):42# 断⾔两数之差的结果是否是243 self.assertEqual(myclass.sub(self.a, self.b), 2, 'test sub fail')444546if__name__ == '__main__':47 unittest.main() # 启动单元测试例⼦3 按特定顺序执⾏⽤例unittest框架⽤例执⾏顺序是按照⽤例名字符的ASCII码顺序⽤例数⼩于10:可将⽤例名命名为test加0-9,按数字由⼩到⼤顺序执⾏⽤例数⼤于10:可将⽤例名字⾸字母开始命名 a-Z按顺序执⾏,如第⼀字母相同,则第⼆字母再按a-Z顺序排序,以此类推suit.addTest(class(‘testcase’)) 按此⽅式添加的⽤例会按添加顺序执⾏此代码需要⽂本开头的被测试模块Calc.py1#encoding=utf-82import unittest3from Calc import Calc45class MyTest(unittest.TestCase):67 @classmethod8def setUpClass(self):9print u"单元测试前,创建Calc类的实例"10 self.c = Calc()1112# 具体的测试⽤例,⼀定要以test开头,执⾏顺序按照字母顺序开头13def test_0add(self):14print"run add()"15 self.assertEqual(self.c.add(1, 2, 12), 15, 'test add fail')1617def test_1sub(self):18print"run sub()"19 self.assertEqual(self.c.sub(2, 1, 3), -2, 'test sub fail')2021def test_2mul(self):22print"run mul()"23 self.assertEqual(Calc.mul(2, 3, 5), 30, 'test mul fail')2425def test_3div(self):26print"run div()"27 self.assertEqual(Calc.div(8, 2, 4), 1, 'test div fail')2829if__name__ == '__main__':30 unittest.main()# 启动单元测试313233if__name__ == '__main__':34 suite = unittest.TestSuite()35 suite.addTest(MyTest(‘test_2mu’))36 suite.addTest(MyTest(‘test_1sub’))37 runner = unittest.TextTestRunner()38 runner.run(suite)例⼦4 忽略测试⽅法,不想执⾏的⽤例,可跳过unittet可以分⽆条件忽略和有条件忽略,通过装饰器实现跳过⽤例时打印括号内后⾯参数的内容(跳过原因)@unittest.skip(reason) 装饰器:⽆条件跳过装饰的测试,并说明跳过测试的原因。

单元测试框架有哪些内容

单元测试框架有哪些内容

单元测试框架有哪些内容单元测试框架是软件开发过程中的重要工具,用于测试单独的函数、方法或类,以确保它们按照预期工作。

一个好的单元测试框架可以大大简化测试过程,并确保软件的质量和稳定性。

在本文中,我们将探讨一些常见的单元测试框架以及它们的主要内容。

JUnitJUnit 是 Java 社区中最流行的单元测试框架之一。

它支持注解和断言,可以方便地编写和运行测试用例。

JUnit 提供了丰富的断言方法,如 assertEquals、assertTrue、assertFalse 等,用于对测试结果进行验证。

JUnit 也提供了丰富的生命周期和扩展点,可以对测试过程进行定制化。

NUnitNUnit 是用于 .NET 平台的一个成熟的单元测试框架。

和 JUnit 类似,NUnit 也支持注解和断言,并提供了丰富的验证方法。

除了基本的单元测试功能外,NUnit还支持参数化测试、并发测试、数据驱动测试等高级功能。

PyTestPyTest 是 Python 社区中广泛使用的一个单元测试框架。

它使用简单,但功能强大。

PyTest 可以自动发现测试用例,并生成测试报告。

它支持标准的断言功能,同时还可以与其他插件和库进行集成,扩展其功能。

MochaMocha 是一个流行的JavaScript 单元测试框架,适用于Node.js 和浏览器环境。

Mocha 使用BDD(行为驱动开发)风格编写测试用例,可以轻松地组织测试套件。

Mocha 支持异步测试、代码覆盖率检测等高级功能,使得 JavaScript 单元测试变得简单而灵活。

PHPUnitPHPUnit 是 PHP 社区中最流行的单元测试框架之一。

它提供了丰富的断言方法和功能,用于测试 PHP 代码的各种情况。

PHPUnit 支持多种测试套件的管理,可以方便地组织和运行大型测试套件。

PHPUnit 还支持测试驱动开发(TDD)和行为驱动开发(BDD)等多种开发模式。

以上是一些常见的单元测试框架及其主要内容。

单元测试框架是自动化测试的基础

单元测试框架是自动化测试的基础

单元测试框架是自动化测试的基础单元测试是软件开发中至关重要的一环,它可以帮助开发人员验证代码的正确性、提高代码质量、防止未来的回归错误等。

在实际的软件开发过程中,单元测试通常会借助于单元测试框架来进行自动化测试,以提高效率并确保测试的一致性。

本文将探讨单元测试框架在自动化测试中的重要性以及常见的单元测试框架。

单元测试框架简介单元测试框架是一种用于编写和执行单元测试的工具集合。

它通常提供了一些预定义的测试方法和断言,可以帮助开发人员编写测试用例和验证代码的输出是否符合预期。

单元测试框架还可以自动化执行测试用例并生成测试报告,从而提高测试效率。

单元测试框架的优点1.提高测试效率: 单元测试框架可以自动化执行测试用例,节省了手动测试的时间和精力。

2.一致性: 单元测试框架可以确保每次测试都是一致的,避免了人为的主观判断造成的误差。

3.便于维护: 单元测试框架可以将测试用例和测试代码分离,使得代码维护更加清晰和简洁。

常见的单元测试框架1.JUnit: JUnit是Java平台上最流行的单元测试框架之一,它提供了丰富的断言方法和生命周期回调函数,可以方便地编写和执行单元测试。

2.pytest: pytest是Python语言中常用的单元测试框架,它支持丰富的插件系统和参数化测试,可以覆盖更多的测试场景。

3.NUnit: NUnit是.NET平台上的单元测试框架,它提供了可视化的测试运行器和强大的断言方法,适用于.NET开发人员进行单元测试。

如何选择单元测试框架在选择单元测试框架时,需要考虑以下几个方面:1.语言和平台: 选择适用于项目开发语言和平台的单元测试框架,确保能够充分发挥框架的功能。

2.社区支持: 选择那些有活跃社区支持和更新频繁的单元测试框架,以便及时获得帮助和解决问题。

3.功能丰富性: 选择功能丰富的单元测试框架,能够满足项目的需求并提高测试的覆盖率和可靠性。

结语单元测试框架是自动化测试的基础,它可以帮助开发人员更好地进行代码测试、提高测试效率和质量。

单元测试框架的作用

单元测试框架的作用

单元测试框架的作用单元测试框架在软件开发中扮演着至关重要的角色。

它是一种自动化测试工具,用于验证代码中的各个单元(函数、方法、类等)是否按照预期功能工作。

单元测试框架的作用主要体现在以下几个方面:1. 提高代码质量单元测试框架可以帮助开发人员在开发过程中及时发现代码中的bug和逻辑错误。

通过编写各种测试用例,开发人员可以验证每个单元的正确性,确保代码的质量和稳定性。

及时修复单元测试中发现的问题,可以提高代码质量,减少后续维护和测试阶段的工作量。

2. 促进代码重构单元测试框架可以帮助开发人员进行代码重构,改进代码的设计和结构。

在进行代码重构时,开发人员可以通过运行单元测试来确保代码修改不会破坏原有的功能和逻辑。

如果代码修改导致某些单元测试失败,开发人员可以立即定位问题并进行修复,确保代码的可维护性和扩展性。

3. 提升开发效率单元测试框架可以提升开发效率,减少调试和测试的时间成本。

通过自动化运行测试用例,开发人员可以快速地验证代码的正确性,避免手工逐个测试的繁琐过程。

在开发过程中,及时运行单元测试可以及早发现问题、定位bug,并快速修复,有助于提升开发效率和项目进度。

4. 保证代码稳定性单元测试框架可以帮助开发人员保证代码的稳定性。

通过编写全面的测试用例覆盖各种场景和边界情况,开发人员可以确保代码在不同环境和条件下都能正常运行。

自动化运行单元测试还可以避免人为因素对测试结果的影响,提高代码的质量和稳定性。

5. 支持持续集成单元测试框架是实现持续集成(Continuous Integration)的关键环节。

持续集成是一种软件开发实践,通过频繁地集成代码、自动化构建和测试,以确保团队成员提交的代码不会破坏主干代码。

单元测试框架可以与持续集成工具(如Jenkins、Travis CI等)结合使用,实现自动化运行测试用例,并及时反馈测试结果,帮助团队快速发现问题并解决。

综上所述,单元测试框架在软件开发中的作用不可忽视。

单元测试框架使用说明

单元测试框架使用说明

单元测试框架使用说明单元测试是软件开发过程中的一项重要活动,它可以帮助开发人员验证代码的正确性并提前发现潜在的bug。

而单元测试框架则是用来辅助编写和运行单元测试的工具。

在选择单元测试框架时,有几个关键因素需要考虑。

首先,框架应该支持您正在使用的编程语言。

另外,框架还应该具有易于理解和使用的语法。

最后,框架应该提供丰富的断言和测试工具,以便于编写全面和可靠的测试用例。

以下是一个通用的单元测试框架的使用说明:1. 安装框架:首先,您需要将测试框架安装到您的开发环境中。

这通常可以通过使用包管理器来完成,例如在Python中使用pip安装。

2. 导入框架:在编写测试用例之前,您需要在测试代码中导入测试框架的相关模块或库。

这通常可以通过使用`import`语句来实现。

3. 编写测试用例:测试用例是用来验证代码是否按照预期进行工作的代码片段。

在编写测试用例时,您需要考虑各种可能的输入和预期输出情况。

测试用例应该尽可能全面和准确地覆盖代码的各个方面。

4. 运行测试用例:一旦编写完测试用例,您就可以使用框架提供的工具来运行这些测试。

运行测试用例时,框架会自动执行测试代码并记录结果。

您可以查看测试报告来了解哪些测试通过,哪些没有通过。

5. 分析测试结果:测试框架通常会生成一个详细的测试报告,其中包含了测试结果的总结和详细信息。

您可以仔细阅读测试报告,查看哪些测试未通过并尝试修复相应的问题。

6. 重复执行和维护:随着代码的更新和优化,您需要定期运行测试用例,以确保代码的正确性和稳定性。

此外,当添加新功能或修复bug时,您还应该相应地更新和扩展测试用例。

总的来说,单元测试框架是提高代码质量和稳定性的重要工具。

它可以帮助开发人员和团队发现和修复潜在的问题,从而提高软件的可靠性和用户体验。

通过按照上述步骤正确使用单元测试框架,您将能够更轻松地编写和运行测试用例,并确保代码的正确性。

单元测试框架的作用是什么

单元测试框架的作用是什么

单元测试框架的作用是什么在软件开发中,单元测试框架扮演着至关重要的角色。

单元测试是软件开发过程中的一项关键步骤,通过使用单元测试框架来管理和执行单元测试,可以有效提高软件质量、节省时间和成本。

本文将探讨单元测试框架的作用和重要性。

什么是单元测试框架单元测试框架是一套用于编写、管理和执行单元测试的工具集合。

它通常包括断言库、测试运行器、测试报告生成器等功能,能够帮助开发人员编写测试用例、自动化执行测试、检查代码覆盖率等。

常见的单元测试框架包括JUnit、Pytest、Mocha等。

单元测试框架的作用检验代码质量单元测试框架可以帮助开发人员编写针对代码中每个单元(函数、方法等)的测试用例。

通过运行这些测试用例,可以验证每个单元的行为是否符合预期,帮助发现潜在的问题和错误。

及早发现并修复问题有助于提高代码质量,减少后期维护成本。

保障代码重构在软件开发过程中,代码重构是一个常见操作,可以改善代码结构、提高代码可读性和可维护性。

但是,重构后的代码容易引入新的bug。

通过运行单元测试,可以确保重构后代码的行为与之前保持一致,保障重构的安全性。

支持持续集成单元测试框架是实现持续集成的关键。

持续集成是一种软件开发实践,开发人员将代码频繁集成到共享代码库中,并通过自动化构建和测试来验证集成的正确性。

单元测试框架可以自动化运行单元测试,提供即时反馈,确保代码集成后没有引入错误。

提高开发效率通过使用单元测试框架,开发人员可以更快速地编写和运行测试用例,自动化测试流程,减少手动测试的工作量。

单元测试框架还提供了丰富的断言库和测试工具,帮助开发人员编写高效的测试用例,提高开发效率。

增强代码可维护性在软件开发过程中,随着代码规模的增长,代码的维护成本也随之增加。

通过建立和维护良好的单元测试套件,可以确保代码的稳定性和可靠性。

单元测试框架可以帮助开发人员快速地定位问题并修复bug,增强代码的可维护性。

结论单元测试框架在软件开发过程中起着至关重要的作用。

白盒测试中的单元测试框架介绍

白盒测试中的单元测试框架介绍

白盒测试中的单元测试框架介绍单元测试是软件开发中不可或缺的环节,它是白盒测试中的一种重要测试方法。

在白盒测试中,单元测试框架作为一种工具,旨在帮助开发人员进行有效的单元测试。

本文将介绍白盒测试中的单元测试框架,并对其中常见的一些框架进行简要的介绍和比较。

一、单元测试的概念和重要性单元测试是指对软件中最小可测试单元进行测试的过程。

这些最小可测试单元可以是函数、方法、类等。

单元测试的主要目的是验证每个单元的功能是否能够按照预期进行工作,并且在发现错误时能够快速定位和修复。

通过进行单元测试,可以提高软件的质量和可维护性,减少开发过程中的错误和风险。

二、单元测试框架的作用和特点单元测试框架是一种工具,可以帮助开发人员自动化地编写、运行和管理单元测试。

它提供了一系列的API和工具,包括断言库、测试运行器、测试报告生成器等,以便开发人员能够更方便、快速地进行单元测试。

单元测试框架的作用和特点如下:1. 提供断言库:断言是单元测试中判断测试结果是否符合预期的一种方法。

单元测试框架提供了丰富的断言库,可以用于验证函数的返回值、异常的抛出等。

2. 支持测试组织和运行:单元测试框架可以帮助开发人员组织和管理测试用例,提供灵活的测试运行机制,包括批量运行、指定运行顺序、并行运行等。

3. 自动生成测试报告:单元测试框架可以生成详细的测试报告,包括测试用例的执行结果、覆盖率报告、错误信息等。

这样可以方便地进行结果分析和错误修复。

4. 提供模拟和桩对象:单元测试框架可以提供模拟对象和桩对象的支持,以便在测试过程中替代真实的依赖对象。

这样可以隔离测试单元,减少对外部环境的依赖性。

三、常见的单元测试框架介绍在白盒测试中,有许多常见的单元测试框架可供选择,下面将对其中一些进行简要介绍和比较。

1. JUnitJUnit是Java平台上最流行的单元测试框架之一。

它提供了一系列的注解、断言库和测试运行器,使得开发人员能够方便地编写和运行测试用例。

测试框架的优势与劣势对比(十)

测试框架的优势与劣势对比(十)

测试框架的优势与劣势对比概述:测试框架是软件测试中的重要工具,它可以提高测试的效率、可靠性和可维护性。

然而,每种测试框架都有其独特的优势和劣势。

本文将对几种常见的测试框架进行对比,旨在帮助读者理解并选择适合其项目的测试框架。

一、自动化测试框架自动化测试框架是目前最常用和成熟的测试框架之一。

其主要优势在于可以减少测试工作量、提高测试覆盖率和测试质量。

自动化测试框架提供了丰富的功能和工具,例如断言库、测试报告生成、测试并行执行等。

这些功能使得测试人员可以快速编写和执行测试用例,更容易识别和排查问题。

然而,自动化测试框架也存在一些劣势。

首先,编写和维护测试脚本需要一定的技术能力和时间投入。

对于非程序员来说,学习和运用自动化测试框架可能会有一定的难度。

其次,自动化测试框架对测试环境和被测系统的稳定性和一致性要求较高。

如果被测系统频繁变更或遇到无法预测的异常情况,自动化测试的可靠性可能会下降。

二、单元测试框架单元测试框架是一种针对软件系统中最小测试单元——函数或方法的测试框架。

它的主要优势在于提供了独立的、可重复的测试环境,使得程序员可以及早发现和修复 bug,并确保代码质量。

通过单元测试,可以保证每个函数在不同情况下的行为和输出符合预期。

然而,单元测试框架也存在一些劣势。

首先,单元测试只能检测到函数内部逻辑错误,无法覆盖整体系统的运行情况。

这就需要在整体测试过程中结合其他类型的测试,如集成测试和系统测试,以保证系统的完整性和稳定性。

其次,编写单元测试需要一定的时间和精力,对于项目时间紧迫的情况可能会增加开发负担。

三、性能测试框架性能测试框架主要用于评估软件系统的性能和稳定性。

通过模拟用户负载、并发请求等场景,可以识别系统中的瓶颈和性能问题。

性能测试框架可以提供一系列性能指标,如响应时间、吞吐量、并发用户数等,帮助开发人员和测试人员了解系统的性能状况。

然而,性能测试框架也存在一些劣势。

首先,性能测试需要投入大量的硬件资源和时间成本,因此在项目初期可能会增加一定的开销。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
代码重构
– 不改变代码的外部行为而改变其内部结构使其更好理解,更 容易扩展的过程
单元测试是重构成功的关键。 重构准则:改变一小步,测试,然后再改变一小步,
测试……
单元测试框架
DotNet
– Nunit – – Nmock – Rhino Mock
Java
Junit Recipes
– 全面讲解Junit的各类应用
重构-改善既有代码的设计 [Martin fowler]
– 第一本全面讲解重构技术的书,作者为OO界的大师Martin fowler
参考资料-在线网址
/index.htm /se/tutorials/junit/ http://www.cs.umanitoba.ca/~eclipse/10-JUnit.pdf /documentation/tuto
– Junit – Jmock – EasyMock
Demo-最简单的一个单元测试
Nunit的Attribute属性说明 [TestFixture] – 表明类 [Test] -- 表明此方法是一个单元测试方法 [Ignore] -- 略过一个测试
测试执行过程
执行SetUp 执行测试方法1 执行TearDown
编写单元测试的十大理由
测试能减少增加新功能时的bug 测试是最好的程序说明文档 测试能降低改变代码的代价 测试能改善代码的设计 测试是重构成为可能 测试强制你去思考软件实现的细节 测试能加快开发进程 测试能减少编写代码的恐惧,带来自信 测试使你的每一片代码都建立的在扎实的基础之上。 可用于回归测试,提高代码的可维护性, 保证代码长期质量。
参考资料-书
测试驱动开发实践指南
– 从头到尾讲解一个测试驱动开发的实际例子[java]
Pragmatic Unit Testing in C# with Nunit
– 实用程序员系列,短小精悍,简单易懂
Pragmatic Unit Testing in Java with Junit
– 实用程序员系列,短小精悍,简单易懂
xUnit测试家族
Junit Nunit HtmlUnit DbUnit JsUnit …..
Demo-猜数字
关键点分析:
– 随机生成不重复的4位数字 – 根据游戏者输入的数字,验证并返回结果
技术和工具
– Winform – C# – Nunit独立版
大话西游之单元测试[转载]
“我知道这个项目bug很多,无法按时完成,即 使老板把我炒了也是应该的。曾经有一个做单 元测试的机会放在我面前,我没有珍惜,等到 后来项目雪崩了才后悔。如果上天能给我再来 一次机会的话,我会对老板说:我要做单元测 试!如果一定要在单元测试上加个日期,我希 望是一直。"
可怜的老兄,我早该告诉他应该先测试,再编码.
执行SetUp 执行测试方法2 执行TearDown ….. 执行SetUp 执行测试方法n 执行TearDown
JUnit
assertTrue(String message, Boolean test) assertFalse(String message, Boolean test) assertNull(String message, Object object) assertNotNull(String message, Object object) assertEquals(String message, Object expected,
rials/docsystem/build/tutorials/junit/junit.pdf /javadoc/junit/framework/
修正编译错误
有问题
调试,为)
测试驱动开发过程
编写测试
重构代码 运行测试, 使其通过
写点代码
编译



修正编译错误


运行测试, 看它失败
测试哲学
不存在不能进行 自动测试的程序。
[Kent Beck]
测试驱动开发技术
单元测试技术
– 对代码片断外部行为的验证 – 单元测试应该是交付代码的必不可少的一部分。
技术特质
开放 坦诚 勇气 批评和自我批评 快乐 沟通 团队协作
软件开发的现实
随着时间的改变,软件也会改变。 每个人都愿意去维护整齐优美的代码。 但是: 如何应付软件随时间的改变而改变? 如何编写健壮优美的代码?
没有进行单元测试的软件开发过程
编写代码
编译
Object actual) (uses equals method) assertSame(String message, Object expected,
Object actual) (uses == operator) assertNotSame(String message, Object expected,
Object actual
NUnit
Assert.AreEqual(Object o1, Object o2); Assert.AreNotEqual(Object o1, Object o2); Assert.AreSame(Object o1, Object o2); Assert.AreNotSame(Object o1, Object o2); Assert.IsTrue(bool condition); Assert.IsFalse(bool condition); Assert.IsNull(Object o); Assert.IsNotNull(Object o);
相关文档
最新文档