How do you unit test regular expressions?

后端 未结 10 724
长发绾君心
长发绾君心 2020-12-12 11:05

I\'m new to TDD, and I find RegExp quite a particular case. Is there any special way to unit test them, or may I just treat them as regular functions?

10条回答
  •  再見小時候
    2020-12-12 11:45

    Use a fixture in your unit test library of choice and follow the usual TDD approach:

    • Check: Tests are green
    • Break the tests by adding a test for the next "feature"
    • Make it green by adjusting the regex (without breaking existing tests)
    • Refactor regex for better readability (e.g. named groups, character classes instead of character ranges, ...)

    Here is a sample fixture stub for spock as a test runner:

    @Grab('org.spockframework:spock-core:1.3-groovy-2.5')
    @GrabExclude('org.codehaus.groovy:groovy-nio')
    @GrabExclude('org.codehaus.groovy:groovy-macro')
    @GrabExclude('org.codehaus.groovy:groovy-sql')
    @GrabExclude('org.codehaus.groovy:groovy-xml')
    
    import spock.lang.Unroll
    
    class RegexSpec extends spock.lang.Specification {
      String REGEX = /[-+]?\d+(\.\d+)?([eE][-+]?\d+)?/
    
      @Unroll
      def 'matching example #example for case "#description" should yield #isMatchExpected'(String description, String example, Boolean isMatchExpected) {
        expect:
        isMatchExpected == (example ==~ REGEX)
    
        where:
        description                                  | example        || isMatchExpected
        "empty string"                               | ""             || false
        "single non-digit"                           | "a"            || false
        "single digit"                               | "1"            || true
        "integer"                                    | "123"          || true
        "integer, negative sign"                     | "-123"         || true
        "integer, positive sign"                     | "+123"         || true
        "float"                                      | "123.12"       || true
        "float with exponent extension but no value" | "123.12e"      || false
        "float with exponent"                        | "123.12e12"    || true
        "float with uppercase exponent"              | "123.12E12"    || true
        "float with non-integer exponent"            | "123.12e12.12" || false
        "float with exponent, positive sign"         | "123.12e+12"   || true
        "float with exponent, negative sign"         | "123.12e-12"   || true
      }
    }
    

    It can be run as a stand-alone groovy script like

    groovy regex-test.groovy
    

    Disclaimer: The snippet is taken from a series of blog posts I wrote some weeks ago

    • Regular Expressions TDD using Java and JUnit 4
    • Regular Expressions TDD using Groovy and Spock
    • Regular Expressions TDD using clojure.test

提交回复
热议问题