自动化测试

概念

  • TDD - Test Driven Development

    Automated testing plays a critical role in software development and maintainance. OpenResty provides a data-driven test scaffold for writing declarative test cases for Nginx C modules, Lua libraries, and even OpenRestry applications...OpenResty itself has been relying on automated testing to remain high quality over the years.

    Most robust software invests heavily on error handling, and naturally test designers focus on corner cases and erroneous scenarios to maximize code coverage of the tests.

    Designing test cases is an art, in many ways. It may, sometimes, take even more time and effort than implementing the feature to be tested.

  • Test::Nginx - Data-driven test scaffold for Nginx C module and Nginx/OpenRestry-based libraries and applications.

    The Test::Nginx scaffold provides a generic simple specification language for expressing and organizing test cases in an intuitive way.

    It also provides various powerful testing modes or "engines" to run the tests in various different ways in the hope of exposing bugs in different settings.

Test::Nginx

It is a test framework that drives test cases written for any code running atop Nginx, and also, naturally, the Nginx core itself.

Written in Perl but the user does not really need to know Perl since It provides a very simple notation to present the test cases in a specificiation-like format.

It is a subclass of Test::Base, and it just provides handy primitives and notations that simplify testing in the Nginx and OpenResty context.

Test::Nginx provides several different testing classes for different user requirements. The most frequently used one is Test::Nginx::Socket.

安装

cpan Test::Nginx

用例规则

  • Test Suite Layout Convention

    • A t/ directory at the root of project source tree;
    • Each test file contains test cases that are closely related in some way and has the file extension .t;
    • When you have many test files, you can also group them further with sub-directories under t/;
    • Each test file is a Perl script file runnable by either perl or Perl's universal test harness tool named prove;
    • A test file usually do not have much Perl code; All of the test cases are declared as cleanly formatted "data" in these .t files;
  • Test File Layout

    • Test::Nginx follows a special design that decomposes each test file into two main parts separated by a special line contains __DATA__:
      • The first part is very short prologue that consists of a few lines of Perl code: to define some special environment variables or Perl variables that can be shared and referenced in the test cases define in the "data part"; to call some other Perl functions imported by Test::Nginx::Socket module to customize the testing configurations and behaviors for the current test file, etc.
      • While the second part is a listing of the test cases in a special data format. This special format is an instance of DSL. The test case specification ("data part") is composed by a a series of test blocks. Each test block usually corresponds to a single test case. A single test case has a title, an optional description*, and **a series of data sections.
    • Test::Nginx takes advantage of Perl's special __DATA__ notation to allow data-driven test case specifications in a simple format or language that is easily understandable by everyone.
  • Test Block/Test Case

    • Block Title - to describe the intention of the current test case.

    • Block Description - a more detailed description of the intention of the test block than the block title.

    • Data Section - every test block carries one or more data sections, it has a name and a value, which specify any input data fields and the expected output data fields.

      • The section name usually contains just alphanumeric letters and underscore characters. Test::Nginx offers various pre-defined data section names for different purposes. Some are for specifying input data, some are for expected output, and some for controlling whether the current test block should be run at all.

        • Some of the special data section names: ONLY, SKIP, LAST.
        • Data sections for Nginx Configuration:
          • main_config - top-level scope
          • http_config - http {} scope
          • config - server {} scope
        • Data sections for request preparation:
          • request
          • pipelined_request
          • raw_request
        • Data sections for checking responses:
          • response_body
          • error_code
          • response_body_like
          • response_headers
          • ignore_response
        • Data sections for checking error logs:
          • error_log and no_error_log
          • grep_error_log and grep_error_log_out
        • Data sections for testing server startup failures:
          • must_die
        • Data sections for testing timeout errors:
          • timeout
      • The section filter is used to adjust or convert the section values in certain ways. They are specified right after the section name with at least one space character as the separator. Multiple filters are aslo separated by spaces and are applied in the order they are written.

        • Some of the section filters: chomp, eval.
      • The section value are specified in two forms: one is all the lines after the section name line; the other form is more concise and specifies the value directly on the same line as the section name, but right after the first colon character (:). The one-line form always excludes the trailing new-line character while the multi-line form always includes one.

    • Test Plan - the exact number of tests we expect current test file to run. If a different number of tests other than the plan were actually run, then the test result would be considered malicious even when all the tests are passed successfuuly.

    • Test Mode - Different test modes have different focuses and squeeze more value out of the tests we already have.

      • Benchmark Mode - export TEST_NGINX_BENCHMARK='2000 2'
      • HUP Reload Mode - export TEST_NGINX_USE_HUP=1
      • Valgrind Mode - export TEST_NGINX_USE_VALGRIND=1
      • Naive Memory Leak Check Mode - export TEST_NGINX_CHECK_LEAD=1
      • Mockeagain Mode
      • Manual Debugging Mode
      • SystemTap Mode
    • A sample:

      === TEST 1: hello, world.
      This is just a simple demonstration of the
      echo directive provided by ngx_http_echo_module
      
      --- config
      location = /t {
          echo "hello, world!";
      }
      --- request
      GET /t
      --- response_body
      hello, world!
      --- error_code: 200
      

运行用例

  • Test::Nginx always invokes a real Nginx server and a real socket client to run the tests. It automatically uses the nginx program found in the system environment PATH. Raw files automatically generated by Test::Nginx, like t/servroot/conf/nginx.conf and t/servroot/logs/error.log, should be checked frequently when manually debugging the test cases.
  • Test files are usually run by the alphabetical order of their file names.
  • By default, the Test::Nginx shuffles the test blocks in each file and run them in a random order. This behavior encourages writing self-contained and independent test cases and also increases the change of hitting a bug by actively mutating the relative running order of the test cases. We can always disable this test block shuffling behavior by calling Perl function, no_shuffle(), before the run_tests() call in the test file prologue.
  • By default, the Test::Nginx starts a new Nginx server before running each test block and shuts down the server immediately after running the block.
% prove t/foo.t
% prove -r t/
Comments

不要轻轻地离开我,请留下点什么...

comments powered by Disqus

Published

Category

Nginx

Tags

Contact