代码之家  ›  专栏  ›  技术社区  ›  Eric

使用pytest,断言与“大”多行字符串比较非常缓慢

  •  1
  • Eric  · 技术社区  · 5 年前

    使用此test_strings.py:

    def test_long_string_compare():
        t1 = 'this is a line that will be repeated many times \n' * 300
        t2 = '-> this is a line that will be repeated many times with some differences \n' * 300
        print('is equal :', t1==t2)
        assert t1 == t2
    
    if __name__ == '__main__':
        test_long_string_compare()
    

    比较300行字符串的测试非常长:

    ========================================================================================================================== test session starts ==========================================================================================================================
    platform linux -- Python 3.6.9, pytest-5.4.3, py-1.8.2, pluggy-0.13.1
    rootdir: /home/elapouya/tmp/tests
    plugins: diff-0.1.14
    collected 1 item                                                                                                                                                                                                                                                        
    
    test_strings.py F                                                                                                                                                                                                                                                 [100%]
    
    =============================================================================================================================== FAILURES ================================================================================================================================
    _______________________________________________________________________________________________________________________ test_long_string_compare ________________________________________________________________________________________________________________________
    
        def test_long_string_compare():
            t1 = 'this is a line that will be repeated many times \n' * 300
            t2 = '-> this is a line that will be repeated many times with some differences \n' * 300
            print('is equal :', t1==t2)
    >       assert t1 == t2
    E       AssertionError: assert 
    E         '-> this is a line that will be repeated many times with some differences \n-> this is a line that will be repeated many times with some differences \n-> this is a line that will be repeated many times with some differences \n-> this is a line that will be repeated many times with some differences \n-> this is a line that will be repeated many times with some differences \n-> this is a line that will be repeated many times with some differences \n-> this is a line that will be repeated many times with some differences \n-> this is a line that will be repeated many times with some differences \n-> this is a line that will be repeated...
    E         
    E         ...Full output truncated (903 lines hidden), use '-vv' to show
    
    test_strings.py:5: AssertionError
    ------------------------------------------------------------------------------------------------------------------------- Captured stdout call --------------------------------------------------------------------------------------------------------------------------
    is equal : False
    ======================================================================================================================== short test summary info ========================================================================================================================
    FAILED test_strings.py::test_long_string_compare - AssertionError: assert 
    =========================================================================================================================== 1 failed in 9.61s ===========================================================================================================================
    
    real    0m9,840s
    user    0m9,817s
    sys 0m0,020s
    

    将近10秒,它是巨大的!

    如果我只执行python脚本:

    time python test_strings.py 
    is equal : False
    Traceback (most recent call last):
      File "test_strings.py", line 8, in <module>
        test_long_string_compare()
      File "test_strings.py", line 5, in test_long_string_compare
        assert t1 == t2
    AssertionError
    
    real    0m0,025s
    user    0m0,020s
    sys 0m0,004s
    

    这快了400倍

    如果使用 pytest --assert=plain ,它要快得多:

    time pytest -vv --assert=plain
    ========================================================================================================================== test session starts ==========================================================================================================================
    platform linux -- Python 3.6.9, pytest-5.4.3, py-1.8.2, pluggy-0.13.1 -- /home/elapouya/.virtualenvs/tests-D190GBZr/bin/python3.6
    cachedir: .pytest_cache
    rootdir: /home/elapouya/tmp/tests
    plugins: diff-0.1.14
    collected 1 item                                                                                                                                                                                                                                                        
    
    test_strings.py::test_long_string_compare FAILED                                                                                                                                                                                                                  [100%]
    
    =============================================================================================================================== FAILURES ================================================================================================================================
    _______________________________________________________________________________________________________________________ test_long_string_compare ________________________________________________________________________________________________________________________
    
        def test_long_string_compare():
            t1 = 'this is a line that will be repeated many times \n' * 300
            t2 = '-> this is a line that will be repeated many times with some differences \n' * 300
            print('is equal :', t1==t2)
    >       assert t1 == t2
    E       AssertionError
    
    test_strings.py:5: AssertionError
    ------------------------------------------------------------------------------------------------------------------------- Captured stdout call --------------------------------------------------------------------------------------------------------------------------
    is equal : False
    ======================================================================================================================== short test summary info ========================================================================================================================
    FAILED test_strings.py::test_long_string_compare - AssertionError
    =========================================================================================================================== 1 failed in 0.02s ===========================================================================================================================
    
    real    0m0,200s
    user    0m0,193s
    sys 0m0,008s
    

    但我正在失去字符串比较。

    我找到了一个解决方法:

    def test_long_string_compare3():
        t1 = 'this is a line that will be repeated many times \n' * 300
        t2 = 'xx this is a line that will be repeated many times \n' * 300
        t1 = t1.splitlines()
        t2 = t2.splitlines()
        lt1 = len(t1)
        lt2 = len(t2)
        if lt1 > lt2:
            t2 += [''] * (lt1-lt2)
        if lt1 < lt2:
            t1 += [''] * (lt2-lt1)
        for i,(left,right) in enumerate(zip(t1,t2)):
            assert left == right, f'Line {i} differs'
    

    但它停留在第一个差异上。

    有没有一种方法可以获得完整的字符串比较,而不会如此缓慢?

    0 回复  |  直到 5 年前
        1
  •  2
  •   jsnklln    4 年前

    我也遇到了这个。最终使用 testfixtures.compare ,似乎工作得很好。