测试体系介绍-L3

一、测试框架体系 TDD DDT BDD ATDD

1.1 测试框架简介

  • 测试框架是一组用于创建和设计测试用例的指南或规则。框架由旨在帮助QA专业人员更有效地测试的实践和工具的组合组成。这些指南可能包括编码标准、测试数据处理方法、对象存储库、存储测试结果的过程或有关如何访问外部资源的信息。
  • A testing framework is a set of guidelines or rules used for creating and designing test cases. A framework is comprised of a combination of practices and tools that are designed to help QA professionals test more efficiently.
    These guidelines could include coding standards, test-data handling methods, object repositories, processes for storing test results, or information on how to access external resources.

1.2 测试框架的价值

  • 测试框架是任何成功的自动化测试过程的重要组成部分。它们可以降低维护成本和测试工作,并为寻求优化其敏捷流程的QA团队提高更高的投资回报率(ROI)。
  • esting frameworks are an essential part of any successful automated testing process. They can reduce maintenance costs and testing efforts and will provide a higher return on investment (ROI) for QA teams looking to optimize their agile processes.

1.3 测试框架的收益

  1. 提高测试效率 Improved test efficiency
  2. 降低维护成本 Lower maintenance costs
  3. 最少的人工干预 Minimal manual intervention
  4. 最大测试覆盖率 Maximum test coverage
  5. 代码的可复用性 Reusability of code

1.4 常用测试框架类型

框架 全称 说明
TDD Test Driven Development 测试驱动开发
DDT Data Driven Testing 数据驱动风格
ATDD Acceptance Test Driven Development 验收测试驱动开发
BDD Behavior Driven Development 行为驱动开发
MBT Model Based Testing 基于模型的测试

二、TDD

2.1 定义

  • 测试驱动开发(TDD)是一个软件开发过程,在软件完全开发之前,将软件需求转换为测试用例,并通过针对所有测试用例重复测试软件来跟踪所有软件开发。这与先开发软件再创建测试用例相反。
  • Test-driven development (TDD) is a software development process relying on software requirements being converted to test cases before software is fully developed, and tracking all software development by repeatedly testing the software against all test cases.

2.2 流程

  1. 单元测试
  2. 重构
  3. 覆盖率
  4. 可测性提升
  5. 模型驱动设计
    image
    TDD来源于XP极限编程

2.3 代表作

1. JUnit

    @Test
    void standardAssertions() {
        assertEquals(2, calculator.add(1, 1));
        assertEquals(4, calculator.multiply(2, 2),
                "The optional failure message is now the last parameter");
        assertTrue('a' < 'b', () -> "Assertion messages can be lazily evaluated -- "
                + "to avoid constructing complex messages unnecessarily.");
    }

2. TestNG

package example1;

import org.testng.annotations.*;

public class SimpleTest {

 @BeforeClass
 public void setUp() {
   // code that will be invoked when this test is instantiated
 }

 @Test(groups = { "fast" })
 public void aFastTest() {
   System.out.println("Fast test");
 }

 @Test(groups = { "slow" })
 public void aSlowTest() {
    System.out.println("Slow test");
 }

3. Pytest

# content of test_sample.py
def inc(x):
    return x + 1


def test_answer():
    assert inc(3) == 5

4. UnitTest

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

三、BDD

3.1 定义

  • 在软件工程中,行为驱动开发(BDD)是一种敏捷软件开发过程,它鼓励软件项目中的开发人员、质量保证专家和客户代表之间进行协作。它鼓励团队使用对话和具体示例来形成对应用程序应该如何运行的共同理解。它源于测试驱动开发(TDD)。行为驱动开发将TDD的通用技术和原则与领域驱动设计和对象的思想相结合,面向分析和设计,为软件开发和团队管理提供共享工具和共享流程,以便在软件开发方面进行协作。
  • behavior-driven development (BDD) is an agile software development process that encourages collaboration among developers, quality assurance experts, and customer representatives in a software project. It encourages teams to use conversation and concrete examples to formalize a shared understanding of how the application should behave. It emerged from test-driven development (TDD). Behavior-driven development combines the general techniques and principles of TDD with ideas from domain-driven design and object-oriented analysis and design to provide software development and management teams with shared tools and a shared process to collaborate on software development.

3.2 与TDD对比


BDD
image
TDD

3.3 BDD相关框架

  • JBehave
  • Cucumber
  • Mspec
  • Specflow

3.4 Cucumber

3.4.1 定义

  • Cucumber是一款支持行为驱动开发(BDD)的工具。
  • Cucumber is a tool that supports Behaviour-Driven Development(BDD).
    imageimage

3.4.2 Cucumber测试用例Scenario场景

Scenario: Finding some cheese
   Given I am on the Google search page
   When I search for "Cheese!"
   Then the page title should start with "cheese"

3.4.3 Cucumber测试用例步骤定义

public class ExampleSteps {

    private final WebDriver driver = new FirefoxDriver();

    @Given("I am on the Google search page")
    public void I_visit_google() {
        driver.get("https://www.google.com");
    }

    @When("I search for {string}")
    public void search_for(String query) {
        WebElement element = driver.findElement(By.name("q"));
        // Enter something to search for
        element.sendKeys(query);
        // Now submit the form. WebDriver will find the form for us from the element
        element.submit();
   }

   @Then("the page title should start with {string}")
   public void checkTitle(String titleStartsWith) {
       // Google's search is rendered dynamically with JavaScript
       // Wait for the page to load timeout after ten seconds
       new WebDriverWait(driver,10L).until(new ExpectedCondition<Boolean>() {
           public Boolean apply(WebDriver d) {
               return d.getTitle().toLowerCase().startsWith(titleStartsWith);
           }
       });
   }

   @After()
   public void closeBrowser() {
       driver.quit();
   }
}


Cucumber项目结构

四、ATDD

4.1 定义

  • 验收测试驱动开发(ATDD)是一种基于客户、开发人员和测试人员之间沟通的开发方法。ATDD包含许多与示例规范(SBE)、行为驱动开发(BDD)、示例驱动开发(EDD)和支持驱动开发(也称为故事驱动开发(SDD))。所有这些流程都有助于开发人员和测试人员在实施之前了解客户的需求,并使客户能够使用它们自己的领域语言进行交流。
  • Acceptance test–driven development (ATDD) is a development methodology based on communication between the business customers, the developers, and the testers. ATDD encompasses many of the same practices as specification by example (SBE), behavior-driven development (BDD), example-driven development (EDD), and support-driven development also called story test–driven development (SDD). All these processes aid developers and testers in understanding the customer’s needs prior to implementation and allow customers to be able to converse in their own domain language.

4.2 ATDD相关工具

  • FitNesse:一个完全集成的独立 wiki 和验收测试框架。
  • FitNesse:The fully integrated standalone wiki and acceptance testing framework.
  • Robot Framework:是一个基于 Python 的、可扩展的关键字驱动自动化框架,用于验收测试、验收测试驱动开发(ATDD)、行为驱动开发(BDD)和机器人流程自动化(RPA)。
  • Robot Framework:is a Python-based,extensible keyword-driven automation framework for acceptance testing,acceptance test driven development(ATDD),behavior driven development(BDD) and robotic process automation(RPA).
    image
    image

4.3 Robot Framework

4.3.1 简介

  • Robot Framework 是一个通用的开源自动化框架。它可用于测试自动化和机器人流程自动化(RPA)。Robot Framework 采用易于理解的语法,使用人类可读的关键词。其能力可以通过用 Python、Java 或许多其他编程语言实现的库来扩展。Robot Framework 围绕它形成了一个丰富的生态系统,包括作为独立项目开发的库和工具。
  • Robot Framework is a generic open source automation framework. It can be used for test automation and robotic process automation (RPA). Robot Framework has an easy syntax, utilizing human-readable keywords. Its capabilities can be extended by libraries implemented with Python, Java or many other programming languages. Robot Framework has a rich ecosystem around it, consisting of libraries and tools that are developed as separate projects.
    image

4.3.2 Robot Framework测试用例

*** Settings ***
Documentation     Simple example using SeleniumLibrary.
Library           SeleniumLibrary

*** Variables ***
${LOGIN URL}      http://localhost:7272
${BROWSER}        Chrome

*** Test Cases ***
Valid Login
    Open Browser To Login Page
    Input Username    demo
    Input Password    mode
    Submit Credentials
    Welcome Page Should Be Open
    [Teardown]    Close Browser

*** Keywords ***
Open Browser To Login Page
    Open Browser    ${LOGIN URL}    ${BROWSER}
    Title Should Be    Login Page

Input Username
    [Arguments]    ${username}
    Input Text    username_field    ${username}

Input Password
    [Arguments]    ${password}
    Input Text    password_field    ${password}

Submit Credentials
    Click Button    login_button

Welcome Page Should Be Open
    Title Should Be    Welcome Page

4.3.3 数据驱动风格

*** Settings ***
Test Template    Login with invalid credentials should fail

*** Test Cases ***                USERNAME         PASSWORD
Invalid User Name                 invalid          ${VALID PASSWORD}
Invalid Password                  ${VALID USER}    invalid
Invalid User Name and Password    invalid          invalid
Empty User Name                   ${EMPTY}         ${VALID PASSWORD}
Empty Password                    ${VALID USER}    ${EMPTY}
Empty User Name and Password      ${EMPTY}         ${EMPTY}

4.3.4 BDD风格

*** Test Cases ***
Valid Login
    Given login page is open
    When valid username and password are inserted
    and credentials are submitted
    Then welcome page should be open

4.4 与TDD、BDD对比

TDD ATDD BDD
受众 开发 开发 测试 客户 开发 测试 客户
过程 代码 DSL 行为
目标 代码调用功能 验收测试 需求 需求

五、MBT

5.1 定义

5.2 edge代表步骤

  • 边代表一个动作,一个过渡。动作可以是 API 调用、按钮点击、超时等。任何将你的测试系统转移到你想要验证的新状态的事情。但请记住,边上没有进行验证。验证只在顶点处发生。
  • An edge represents an action, a transition. An action could be an API call, a button click, a timeout, etc. Anything that moves your System Under Test into a new state that you want to verify. But remember, there is no verification going on in the edge. That happens only in the vertex.

5.3 vertex代表断言

  • 顶点代表验证,一个断言。验证是你在代码中会有断言的地方。就在这里,你验证 API 调用返回了正确的值,按钮点击确实关闭了对话框,或者当应该发生超时时,测试系统触发了预期的事件。
  • A vertex represents verification, an assertion. A verification is where you would have assertions in your code. It is here that you verify that an API call returns the correct values, that a button click actually did close a dialog, or that when the timeout should have occurred, the System Under Test triggered the expected event.

5.4 graph代表测试用例集

  • 模型是一个图,它是一组顶点和边。从一个模型中,GraphWalker 将生成一条通过它的路径。模型有一个起始元素,以及一个规则如何生成路径的生成器,和一个关联的停止条件,告诉 GraphWalker 何时停止生成路径。
  • A model is a graph, which is a set of vertices and edges From a model, GrapWalker will generate a path through it. A model has a start element, and a generator which rules how the path is generated, and associated stop condition which tells GraphWalker when to stop generating the path.

5.5 测试用例样板生成

@GraphWalker(value = "random(edge_coverage(100))")
public class OwnerInformationTest extends ExecutionContext implements OwnerInformation {

    private static final Logger log = LoggerFactory.getLogger(OwnerInformationTest.class);

    @Override
    public void v_OwnerInformation() {
        $(By.tagName("h2")).shouldHave(text("Owner Information"));
        setAttribute("numOfPets", Value.asValue($$x("//table/tbody/tr/td//dl").size()));
        log.info("Number of pets: " + getAttribute("numOfPets"));
    }

    @Override
    public void e_UpdatePet() {
        $("button[type=\"submit\"]").click();
    }

    @Override
    public void v_FindOwners() {
        $(By.tagName("h2")).shouldHave(text("Find Owners"));
        $(By.tagName("h2")).shouldBe(visible);
    }

    @Override
    public void e_EditPet() {
        $(By.linkText("Edit Pet")).click();
    }

    @Override
    public void e_AddNewPet() {
        $(By.linkText("Add New Pet")).click();
    }

    @Override
    public void e_AddVisit() {
        $(By.linkText("Add Visit")).click();
    }

    @Override
    public void e_FindOwners() {
        $("[title='find owners']").click();
    }

    @Override
    public void e_AddPetSuccessfully() {
        Date date = new Faker().date().past( 365 * 20, TimeUnit.DAYS);
        SimpleDateFormat sdf;
        sdf = new SimpleDateFormat("yyyy-MM-dd");
        String birthData = sdf.format(date);
        $(By.id("birthDate")).clear();
        $(By.id("birthDate")).sendKeys(birthData + Keys.ENTER);

        $(By.id("name")).clear();
        $(By.id("name")).sendKeys(new Faker().name().fullName());

        $(By.id("type")).selectOption(new Faker().number().numberBetween(0,5));
        $(By.cssSelector("button[type=\"submit\"]")).click();
    }

    @Override
    public void v_NewPet() {
        $(By.tagName("h2")).shouldHave(text("New Pet"));
        $(".has-feedback").shouldBe(visible);
    }

    @Override
    public void e_VisitAddedSuccessfully() {
        $(By.id("description")).clear();
        $(By.id("description")).sendKeys(new Faker().lorem().word());
        $("button[type=\"submit\"]").click();
    }

    @Override
    public void v_NewVisit() {
        $(By.tagName("h2")).shouldHave(text("New Visit"));
    }

    @Override
    public void v_Pet() {
        $(By.tagName("h2")).shouldHave(text("Pet"));
    }

    @Override
    public void e_AddPetFailed() {
        $(By.id("name")).clear();
        $(By.id("birthDate")).clear();
        $(By.id("birthDate")).sendKeys("2015/02/05" + Keys.ENTER);
        $(By.id("ui-datepicker-div")).shouldBe(not(visible));
        $(By.id("type")).selectOption("dog");
        $("button[type=\"submit\"]").click();
    }

    @Override
    public void e_VisitAddedFailed() {
        $(By.id("description")).clear();
        $("button[type=\"submit\"]").click();
    }
}

六、DTT

6.1 定义

  • 数据驱动测试(DDT),也称为表驱动测试或参数化测试,是一种软件测试方法,用于计算机软件的测试,用于描述使用条件表直接作为测试输入和可验证输出完成的测试以及测试环境设置和控制没有硬编码的过程。
  • Data-driven testing (DDT), also known as table-driven testing or parameterized testing, is a software testing methodology that is used in the testing of computer software to describe testing done using a table of conditions directly as test inputs and verifiable outputs as well as the process where test environment settings and control are not hard-coded.

6.2 DDT相关工具

  • DDT是一种实践,可以跟很多框架结合;
  • 单元测试结合DDT:JUnit4,JUnit5,TestNG;
  • Robot Framework DDT;
  • YAML、JSON、CSV驱动HttpRunner。

6.3 数据驱动应用

  • HttpRunner可以根据代理抓包自动生成测试用例;
  • YAPI、Swagger等工具可以根据数据自动生成测试用例代码;
  • JVM-Sandbox-Repeater Gor录制工具可以把请求保存为测试用例并重放,以实现快速回归测试。

6.4 HttpRunner测试框架

6.5 HttpRunner测试用例

config:
  name: "request methods testcase with functions"
  variables:
    foo1: config_bar1
    foo2: config_bar2
    expect_foo1: config_bar1
    expect_foo2: config_bar2
  base_url: "https://postman-echo.com"
  verify: False
  export: ["foo3"]

teststeps:
  - name: get with params
    variables:
      foo1: bar11
      foo2: bar21
      sum_v: "${sum_two(1, 2)}"
    request:
      method: GET
      url: /get
      params:
        foo1: $foo1
        foo2: $foo2
        sum_v: $sum_v
      headers:
        User-Agent: HttpRunner/${get_httprunner_version()}
    extract:
      foo3: "body.args.foo2"
    validate:
      - eq: ["status_code", 200]
      - eq: ["body.args.foo1", "bar11"]
      - eq: ["body.args.sum_v", "3"]
      - eq: ["body.args.foo2", "bar21"]
  - name: post raw text
    variables:
      foo1: "bar12"
      foo3: "bar32"
    request:
      method: POST
      url: /post
      headers:
        User-Agent: HttpRunner/${get_httprunner_version()}
        Content-Type: "text/plain"
      data: "This is expected to be sent back as part of response body: $foo1-$foo2-$foo3."
    validate:
      - eq: ["status_code", 200]
      - eq:
          [
            "body.data",
            "This is expected to be sent back as part of response body: bar12-$expect_foo2-bar32.",
          ]
  - name: post form data
    variables:
      foo2: bar23
    request:
      method: POST
      url: /post
      headers:
        User-Agent: HttpRunner/${get_httprunner_version()}
        Content-Type: "application/x-www-form-urlencoded"
      data: "foo1=$foo1&foo2=$foo2&foo3=$foo3"
    validate:
      - eq: ["status_code", 200]
      - eq: ["body.form.foo1", "$expect_foo1"]
      - eq: ["body.form.foo2", "bar23"]
      - eq: ["body.form.foo3", "bar21"]

6.6 数据驱动风格受欢迎的原因

  • 维护成本最低,录制回放技术越来越成熟,可以与数据驱动很好的结合。
  • 低代码、用例生成技术的流行,会让数据驱动风格更受欢迎。

七、持续集成体系

7.1 传统开发流程

7.2 敏捷开发流程

7.3 持续集成

亚马逊给出的定义:

  • 持续集成是一种DevOps软件开发实践。
  • 采用持续集成时,开发人员会定期将代码变更合并到一个中央存储库中,之后系统会自动运行构建和测试操作。
  • 持续集成通常是指软件发布流程的构建或集成阶段,需要用到自动组件化(如CI或构建服务)和文化组件(如学习频繁地集成)。
  • 持续集成的主要目标是更快发现并解决缺陷,提高软件质量,并减少验证和发布新软件更新所需的时间。

7.3.1 GitLab CI流程

7.3.2 自动化测试持续集成


7.4 持续交付

亚马逊给出的定义:

  • 持续交付是一种软件开发实践,通过持续交付,系统可以自动将代码更改发布到生产环境做好准备。
  • 作为现代应用程序开发的支柱,持续交付通过在构建阶段后,将所有代码变更部署到测试环境或生产环境中,实现对持续集成的扩展。
  • 在正确实施时,开发人员将始终拥有一个待发布的代码版本。
  • 采用持续交付时,开发人员可以自动执行单元测试以外的测试,这样他们就可以在部署到客户环境钱跨多个维度对应用程序更新进行验证。
  • 这些测试可能包括UI测试、负载测试、集成测试、API可靠性测试等。
  • 这有助于开发人员更全面地验证更新并抢先发现其中的问题。

7.4.1 持续集成与持续交付

7.4.2 持续交付流水线

7.4.3 流水线构建

7.4.4 GitLab CD流程

7.5 持续部署

Microsoft 给出的定义:

  • 通过持续部署,可自动完成从代码提交到生产的全过程。
  • 开发与交付阶段之间的触发器是自动的,因此,在代码更改获得验证并通过所有测试后,就会立即发布。
  • 这意味着,在改进功能可用后,客户便可立即获得这些功能。

7.5.1 持续集成、持续交付、持续部署

7.6 DevOps体系

  • 持续集成
  • 持续交付
  • 微服务
  • 基础设施即代码
  • 监控和日志记录
  • 沟通与合作

7.6.1 DevOps相关技能

7.6.2 DevOps中的左移与右移

image

八、测试左移体系

8.1 定义

  • 测试左移是一种软件开发方法,强调尽早在开发周期内引入测试和质量保证措施,以提前发现并解决问题,从而减少后期修复的成本和复杂性。
    image
    Applied Software Measurement, Capers Jones(卡珀斯·琼斯), 1996

8.2 微软的左移实践

image

8.3 测试左移主要实践

  • 需求分析与评审:在软件开发的早期阶段,团队成员(包括开发人员、测试人员、项目管理人员等)共同审查需求文档,确保需求的完整性、一致性和可测试性。通过早期识别潜在的问题和歧义,可以减少后期开发过程中的返工。

  • 代码评审:在代码编写阶段,通过同行评审(Peer Review)的方式,其他开发人员审查代码,以发现和修正错误、提高代码质量和可维护性。这有助于在代码合并到主分支之前,发现潜在的问题。

  • 代码审计、代码静态分析:使用自动化工具进行代码审计和静态分析,以检测代码中的安全漏洞、性能问题和代码规范的遵循情况。这可以在不执行代码的情况下发现问题,是早期缺陷检测的有效方式。

  • 自动化测试左移:将自动化测试集成到开发流程的早期阶段,确保在代码编写和提交的过程中就能自动运行测试。这有助于快速反馈测试结果,使得问题可以在较低的成本下修正。

  • 单元测试:开发人员编写单元测试,来验证各个组件或功能模块的行为符合预期。单元测试是测试左移策略中的关键组成部分,有助于确保代码的质量和功能的正确性。

  • 覆盖率统计:通过统计测试覆盖率,评估测试的广度和深度,确保重要的代码路径和决策点都经过了测试。覆盖率的高低可以指示潜在的测试盲点。

  • 应用监控:在软件部署后,实施实时监控和日志记录,以持续跟踪应用的性能和健康状况。这有助于快速发现和解决生产环境中的问题。

  • 测试用例生成:利用自动化测试和技术生成测试用力,以确保测试的全面性和一致性。自动生成的测试用例可以覆盖更多的使用场景和边界条件,提高测试的有效性。

8.4 代码审查 Code Review

  • 代码审查是指对计算机源代码系统化地审查,常用软件同行评审的方式进行,其目的是找出及修正在软件开发初期未发现的错误,提升软件质量及开发者的技术。代码审查常以不同的形式进行,例如结对编程、非正式的看过整个代码,或是正式的软件检查。

8.5 开发人员收益

  • 工作认真且始终如一;
  • 向其他开发人员学习最佳实践和新技术;
  • 在代码库中实现一致性和质量。

8.6 Code Review可以发现哪些问题

  • 设计:代码是否经过精心设计并适合代码库?
  • 功能:代码是否按预期以及对用户有益的方式执行?
  • 复杂性:其他开发人员能否理解和使用代码?
  • 命名:代码是否包含变量、类和方法等元素的清晰名称?
  • 注释:注释是否具体且完整?

8.7 Gerrit Code Review


8.8 GitLab Merge Request Code Review


8.9 代码审计平台SonarQube

SonarQube项目分析案例:

8.10 覆盖率集成

经典bug案例:

九、测试右移

9.1 定义

  • 右移是在实际条件下,在生产中执行测试、质量和性能评估的做法。
  • 右移方法确保在生产中运行的应用程序,可以承受真实的用户负载,同时确保同样高水平的质量。
  • 通过右移,DevOps团队测试构建的应用程序,以确保性能、弹性和软件可靠性。
  • 目标是检测和修复在开发环境中难以预料的问题。

9.2 测试右移的主要实践

测试右移是指在软件开发周期的后期,特别是在软件已经部署到生产环境后,采取的测试和质量保障措施。这种方法的目标是确保在实际运行环境中,软件的稳定性、性能和用户满意度。

主要实践:

  • 应用监控:持续监控应用程序的性能和行为,以确保它在生产环境中表现良好。这包括监控系统资源利用率、响应时间和实物速率等关键性能指标。

  • 综合监控与质量监控(Continuous Quality Monitoring):不仅监控应用的性能指标,还包括对应用质量的全面监控。这涵盖了错误率、用户满意度、功能性断言验证等多个维度,以全方位评估软件的质量。

  • A/B测试:通过将用户分流,对比两个或多个版本的应用程序,来测试新功能或改进的效果。这种方法有助于理解哪些改变能够更好地满足用户需求,从而做出数据驱动的策略。

  • 金丝雀部署(Canary Release):逐步在生产环境中发布新版本的应用程序,先在小部分用户中测试新功能。如果这部分用户没有遇到问题,那么逐步扩大到更多的用户,最终全面部署。这样可以减少新版本可能引入的风险。

  • TIP线上测试(Testing in Production):直接在生产环境中进行测试,以获得最真实的用户反馈和软件表现数据。这需要高度的监控和快速回滚机制,以确保最小化对用户的影响。

  • 故障注入/混沌工程(Chaos Testing):故意在生产环境中引入故障(如服务延迟、系统资源限制等),以测试系统的弹性和回复能力。混沌工程有助于发现和修复在传统测试环境中难以发现的问题,从而提高系统的可靠性。
    image

9.3 测试右移案例

9.3.1 百度前端性能监控

9.3.2 APP崩溃监控



9.4 监控系统搭建

构建一个监控系统,特别是用于收集和分析测试数据,可以为团队提供关键的洞察,帮助优化产品性能和用户体验。

主要步骤:

  • 测试数据收集
    • 确定收集数据的关键指标:首先,需要确定哪些性能指标和用户数据是最重要的。可能包括响应时间、错误率、系统资源使用率(CPU、内存、磁盘I/O等)、用户交互事件等。

    • 使用合适的工具和技术进行数据收集:可能包括日志收集器、APM(应用性能监控)工具、用户行为跟踪工具等。确保这些工具能够以最小的性能影响收集数据。

    • 确保数据的完整性和安全性:在收集数据时,需要确保数据的安全性和隐私性,特别是涉及用户数据时。此外,保持数据的完整性对于后续的分析至关重要。

  • 测试数据分析
    • 自动化分析流程:通过设置自动化脚本或使用专业的数据分析工具,对收集到的数据进行预处理和分析。这包括清洗数据、标准化格式、识别趋势和模式等。

    • 异常检测和根因分析:使用统计学方法和机器学习模型来识别数据中的异常模式。一旦检测到异常,立即进行根因分析,以确定问题的来源。

    • 性能优化和改进建议:基于数据分析的结果,提出性能优化措施和改进建议。这可能包括代码优化、架构调整、资源增配等。

  • 测试数据可视化与分析
    • 构建仪表盘和报告:使用数据可视化工具(如Grafana、Kibana、Tableau等)构建仪表盘,将关键性能指标和趋势以图标形式展现。这有助于团队快速理解系统的当前状态和性能趋势。

    • 实时监控和警报:设置实时监控和警报系统,以便在性能出现异常时立即通知团队。这可以基于预定义的阈值或异常检测算法来实现。

    • 分享和写作:确保监控系统的数据和分析结果,可以轻松地被团队成员访问和共享。促进跨部门之间的协作,共同解决问题和优化性能。

9.5 常用架构 ELK ElasticStack

ELK Stack,也被称为Elastic Stack,是一组开源软件产品的组合,用于搜索、分析和可视化日志生成的数据。ELK分别代表Elasticsearch、Logstash和Kibana,这三个产品联合使用,提供了一个强大的日志管理和分析解决方案。随后,Beats加入了ELK Stack,使其更名为Elastic Stack。

  1. Elasticsearch
    Elasticsearch是一个分布式搜索和分析引擎,基于Lucene构建。它能够快速地存储、搜索和分析大量数据。Elasticsearch是Elastic Stack的核心,提供了数据索引、搜索和分析的功能。它是高度可扩展的,支持多租户。

  2. Logstash
    Logstash是一个服务器端的数据处理管道,能够同时从多个源收集数据,转换数据,然后将数据发送到你指定的目的地。Logstash用于日志和事件数据的收集、处理和转发。它支持多种输入、过滤和输出插件,可以灵活地处理不同格式的数据。

  3. Kibana
    Kibana是一个Web界面,为Elasticsearch中存储的数据提供了可视化能力。使用Kibana,用户可以创建强大的仪表盘,展示实时数据,进行数据分析,以及进行搜索和探索。它提供了一种简单易用的方式来查看、搜索和交互处理存储在Elasticsearch中的数据。

  4. Beats
    Beats是一个轻量级的单一目的数据采集器。它被设计为以Agent的形式安装在服务器上,用于采集各种类型的数据并发送到Elasticsearch或Logstash。Beats系列包括多种专门用途的Beats,如Filebeat用于日志文件、Metricbeat用于收集指标、Packetbeat用于网络数据等。

ELK ElasticStack应用:

使用场景和优势:

Elastic Stack广泛应用于日志收集、监控、安全信息和事件管理(SIEM)、应用性能监控(APM)等领域。其主要优势包括:

  • 强大的数据处理能力:能够处理PB级别的数据。
  • 高度可扩展性:可根据需要水平扩展,满足不同规模的企业需求。
  • 实时分析和可视化:提供实时数据分析和丰富的数据可视化选项。
  • 灵活性和开放性:支持多种数据源和丰富的插件生态系统。

9.6 发布后的质量监控

9.6.1 全流程质量监控

全流程质量监控是一种综合性的质量保证策略,旨在软件开发的每个阶段都实施监控和测试,以确保产品质量从开发到上线后的全生命周期都得到保障。

关键步骤和实践:

1. 研发自测

  • 实施单元测试和代码审查:开发人员应编写单元测试来验证代码模块的功能,并通过代码审查来提高代码质量。
  • 使用静态代码分析工具:自动检测代码中的潜在问题,如安全漏洞、代码异味等。

2. 内部测试

  • 集成测试:测试不同模块或服务之间的交互,确保它们能够协同工作。
  • 性能测试:模拟不同的负载情况,确保系统在高负载下仍能保持良好性能。
  • 安全测试:检查应用是否有潜在的安全风险。

3. 公测

  • 邀请外部用户参与:收集更广泛的用户反馈,发现可能在内部测试中未被发现的问题。
  • 使用Beta测试平台:通过平台收集用户反馈和使用数据,进一步改进产品。

4. 线上监控

  • 实时性能监控:使用APM工具监控应用性能,如响应时间、错误率等。
  • 用户行为分析:跟踪用户行为,了解用户如何与应用互动。

5. 监控分析测试覆盖度

  • 自动化测试覆盖率分析:评估自动化测试覆盖的代码量,确定未被测试代码的风险。
  • 持续集成/持续部署(CI/CD):集成自动化测试到CI/CD流程,确保代码变更都经过测试。

6. 定位问题

  • 日志管理和分析:收集和分析日志数据,快速定位生产环境中的问题。
  • 错误跟踪和反馈循环:使用错误跟踪工具,快速响应用户报告的问题。

7. 监控使用人数

  • 分析用户增长和活跃度:监控应用的用户增长趋势和活跃用户数,评估产品的市场接受度。

8. 监控使用深度

  • 功能使用分析:了解用户最常使用的功能,以及使用频率低的功能,为产品迭代提供指导。

通过全流程质量监控,组织可以确保产品在整个开发周期内都保持高质量标准,及时发现并解决问题,提高用户满意度,并加快产品上市时间。这种方法促进了跨团队的协作,确保质量是整个开发过程的共同责任。

9.7 移动端监控

9.7.1 移动端插桩与埋点

1. 硬编码埋点

  • 定义:开发者直接在代码中手动添加埋点代码,以捕获特定事件或用户行为;

  • 优点:能精确控制数据采集的时机与内容;

  • 缺点:增加了代码的维护成本,对于复杂应用可能会变得难以管理。

2. AOP编程:AspectJ

  • 定义:AOP(面向切面编程)允许开发者通过定义“切面”来插入代码到应用程序的关键路径,比如方法调用或属性访问上,而不修改实际的业务逻辑代码。
  • 优点:减少了代码侵入性,使得埋点和业务逻辑分离,易于维护和管理。
  • 应用:AspectJ是Java语言的一个AOP框架,广泛应用于Android的性能监控和用户行为追踪。

3. 插桩框架:ASM、JavaAssist

  • 定义:这些框架允许在编译期或运行期对字节码进行操作,实现自动化插桩。

  • 优点:自动化程度高,减少手动埋点的工作量,更适合大型项目。

  • ASM:一个轻量级Java字节码操作框架,通过直接操作字节码的方式,实现了极高的性能和灵活性。

  • JavaAssist:提供了更易于使用的API来操作字节码,适合需要动态生成或修改类的应用场景。

9.7.2 数据收集回传

1. Logstash

  • 用途:一个强大的数据收集、转换和传输的服务器端工具,支持多种输入、过滤和输出插件。
  • 应用场景:适用于收集和处理日志、事件等数据,然后将数据传输到指定的存储或分析系统,如Elastic search。

2. Kafka

  • 用途:一个分布式流处理平台,用于构建实时的数据管道和流应用程序。
  • 应用场景:适用于高吞吐量的数据收集场景,如用户行为数据、应用性能指标等的实时处理和分析。

3. Filebeat

  • 用途:轻量级的日志文件收集器,用于监控日志文件或位置,并将日志数据转发到Logstash、Elasticsearch等处理系统。
  • 应用场景:适用于收集和转发移动端产生的日志文件,支持自动化地处理和分析日志数据。

9.7.3 插桩技术

插桩技术是在软件开发领域中,用于监控、分析和调试代码行为地一种技术。通过在应用程序的代码中添加额外的代码段(称为“插桩代码”),开发者可以收集关于程序运行时行为的信息,比如性能数据、功能使用情况和运行时错误。插桩技术可以根据其实现方式和使用时机分为不同的类别,包括基于编译的插桩、基于DEX的插桩和使用Hook技术的方法。

1. 基于编译插桩

  • 定义:这种方法在源代码编译成可执行程序的过程中,自动或手动地添加插桩代码。这要求在编译时期就要决定插入哪些监控代码,因此需要对源代码或字节码进行操作。

  • 例子:NewRelic SDK是一个应用性能管理(APM)工具,它通过在编译阶段自动插入监控代码来收集应用性能数据,帮助开发者分析和优化代码。

  • 优点:能够在应用运行前进行全面的插桩,无需修改源代码,适合细粒度的性能监控和分析。

  • 缺点:可能会增加编译复杂性,对编译过程有一定的侵入性。

2. 基于DEX插桩

  • 定义:DEX(Dalvik Executable)文件是Android平台上应用程序代码的打包格式。基于DEX的插桩是指在DEX文件生成后、运行前对其进行操作,添加监控代码。

  • 例子:Appetizer.io提供了一种自动化的DEX插桩技术,可以在应用构建的后期阶段插入监控代码,用于性能监测和分析。

  • 优点:相对于源代码插桩,这种方式对原有开发流程的影响更小,便于集成和使用。

  • 缺点:在一定程度上依赖于DEX格式,主要适用于Android平台。

3. Hook技术

  • 定义:Hook技术通过拦截系统调用、函数调用或消息传递等,动态地插入或修改代码地执行。这种方法不需要修改应用本身地代码,而是在运行时动态地添加监控或修改行为。

  • 例子1:Xposed是一个框架,允许在不修改APK地情况下修改Android系统和应用行为。通过使用Xposed模块,开发者可以针对特定的方法或事件实施Hook。

  • 例子2:Frida是一个动态代码插桩工具,支持包括Android、iOS在内的多个平台。Frida允许开发者在应用允许时注入自己的脚本,以监控和修改应用行为。

  • 优点:极高的灵活性和强大的功能,适合于复杂的分析、调试和安全测试任务。

  • 缺点:需要深入了解目标应用的内部结构和运行机制,使用门槛较高。

9.7.4 常见质量维度的监控类型

监控质量维度是确保应用稳定性、性能和用户满意度的关键。

1. APP崩溃

  • 定义:捕获和分析应用崩溃的原因,帮助开发者快速定位和解决问题。

  • 例子:Bugly是一个腾讯提供的稳定性管理平台,它提供崩溃监控、应用升级等功能,可以帮助开发者监控和改善应用的稳定性。

2. 应用性能监控(APM)

  • 定义:监控应用的运行性能,包括响应时间、资源使用率、网络请求等,以确保用户获得流畅的体验。

  • 例子:APM(应用性能管理)工具,如New Relic、Dynatrace等,提供实时性能监控、故障诊断和优化建议。

3. 业务监控

  • 定义:追踪应用的关键业务指标,如用户活跃度、转化率、收入等,帮助开发者理解业务表现和用户行为。

  • 例子1:TalkingData提供用户分析、广告效果追踪等功能,帮助开发者优化产品和营销策略。

  • 例子2:友盟Umeng,一个综合性的移动统计分析平台,提供应用统计、用户行为分析等服务。

4. 质量监控

  • 定义:综合监控应用的稳定性、性能和用户体验等多个维度的质量指标。

  • 缺点:对于“质量监控”这一术语,虽然目前没有一个单独的工具或平台被广泛认可,但多数APM和业务监控工具都提供了覆盖这些维度的功能。

5. 精准化测试平台

  • 定义:提供自动化测试、性能测试和安全测试等服务的平台,帮助开发者在应用发布前识别和修复潜在的质量问题。

  • 例子:Sauce Labs、BrowserStack等,这些平台提供了在多种真是设备和环境下进行自动化测试的能力,帮助确保应用的兼容性和性能。

9.7.5 常见数据存储平台

在现代软件和系统架构中,数据的收集、存储、分析及展现是提供洞察和支持决策的关键。

【数据同步】

1. Logstash

  • 用途:一个开源的服务器端数据处理管道哦,能够同时从多个源收集数据,转换数据,然后发生到所选的“存储库”中。
  • 特定:支持多种输入、过滤和输出插件,可以灵活地处理不同格式地数据,是Elastic Stack的一个组成部分。

2. Flume

  • 用途:Apache Flume是一个分布式、可靠且可用的系统,用于有效地收集、聚合和移动大量日志数据到集中式数据存储。
  • 特点:设计用于高吞吐量的数据传输,Flume支持复杂的数据流拓扑结构,使得数据同步既灵活又可靠。

【数据存储】

1. Elasticsearch

  • 用途:一个基于Lucence的搜索和分析引擎。Elasticsearch能够快速地存储、搜索和分析大量数据。

  • 特点:非常适合与日志和时间序列数据一起使用,支持实时搜索,是Elastic Stack的核心。

2. InfluxDB

  • 用途:一个开源的时间序列数据库,专为速度、高可用性和可扩展性而设计。

  • 特点:非常适合用于存储和分析时间序列数据,如监控指标、传感器数据等。

3. Prometheus

  • 用途:一个开源的监控和警报工具,专门设计用于处理高维数据。

  • 特点:其强大的查询语言(PromQL)特别适合于处理时间序列数据,广泛用于云原生应用的监控。

【前端展现】

1. Kibana

  • 用途:一个开源的前端应用,与Elasticsearch搭配使用,提供日志和时间序列数据的可视化。
  • 特点:支持创建复杂的查询、图表和仪表盘,使得数据分析和监控变得直观易懂。

2. Grafana

  • 用途:一个开源平台,用于监控和分析。支持多数据源,如Prometheus、InfluxDB等。

  • 特点:提供了丰富的可视化选项,包括图表、表格、地图等,以及强大的警报功能。

9.7.6 数据检索

9.7.7 数据统计


9.7.8 数据分析


9.7.9 测试执行分析

9.7.10 漏测分析

9.7.11 关联分析

9.7.12 更多数据收集

  • 用户反馈分析
  • 核心用户在产品内的反馈
  • 应用商店评论
  • 进行汇总分析
  • 产品反馈
  • 外部平台:Bugly、友盟Umeng、Flurry

9.7.13 业务建模

  • 建模
    • UI模型
    • 接口模型
    • 性能数据
    • 代码流模型
  • 分析
    • 基于规则
    • diff算法
    • 机器学习+AI

十、精准测试体系

10.1 定义

  • 百度百科:精准测试是一套计算机测试辅助分析系统。精准测试的核心组件包含的软件测试示波器、用例和代码的双向追溯、智能回归测试用例选取、覆盖率分析、缺陷定位、测试用例聚类分析、测试用例自动生成系统,这些功能完整地构成了精准测试技术体系。

  • 阿里:通过建立测试用例与业务方法的关联关系,在代码发生变化时,精准的推荐出需要运行的用例,进行测试执行与结果反馈。通过精准的圈定测试范围,可以带来效率和速度的双重收益。

  • Thoughtworks:利用技术手段对测试过程产生的数据进行采集存储,计算,汇总,可视化最终帮助团队提升软件测试的效率、并对项目整体质量进行改进和优化的这一系列操作。

  • 网易:精准测试是一套计算机测试辅助分析系统。使用用例和代码两个关键因子,进行质量综合考量和分析的创新测试理论方法体系,核心组件包含软件测试示波器、用例和代码的双向追溯、智能回归测试用例选取、覆盖率分析、缺陷定位、测试用例聚类分析、测试用例自动生成系统,这些功能完整的构成了精准测试技术体系。

10.2 阿里云效精准测试实施案例

image
image

10.3 精准测试案例(Thoughtworks)

10.4 精准测试的应用价值

  • 基于测试用例与代码的关联数据分析,实现测试覆盖改进的方法。
    • 根据代码变更定位测试用例范围
    • 根据代码覆盖精准改进测试用例
    • 测试用例漏测精准定位
    • 基于大数据反推有效测试用例

10.5 行业经典案例

  • 百度利用覆盖率增量从回归数据中提取有效覆盖
  • 精准定位用例数据与覆盖率关系
  • 代码行为流建模
  • 星云测试
  • 有赞集成测试覆盖率统计实践
  • 蚂蚁金服的代码实时染色
  • 有赞精准测试实践
  • 网易精准测试
  • 阿里云效

10.6 精准测试实现技术

10.6.1 关键技术点

  • 静态分析
    • 语法树分析 Javaparser、antlr
    • 代码变更 Git、Diff
    • 字节码分析 ASM
  • 动态分析
    • 覆盖率 JaCoCo
    • 插桩 JVM-SANDBOX、ByteBuddy
    • 流程追踪 Debug、Trace、Hook
  • 测试用例