2013-09-16 18 views
13

ho individuato alcuni test pytest lungo in esecuzione conPosso eseguire line_profiler su un test di pytest?

py.test --durations=10 

vorrei strumento uno di quei test ora con qualcosa come line_profiler o cprofile. Voglio davvero ottenere i dati del profilo dal test stesso, poiché l'installazione o la demolizione pietosa potrebbero far parte di ciò che è lento.

Tuttavia, dato che in genere line_profiler o cprofile sono coinvolti, non mi è chiaro come farlo funzionare con pytest.

risposta

6

Per ottenere cProfile e line_profiler di lavorare con py.test codice, ho fatto due cose:

  1. estesa il codice di prova py.test con una chiamata a pytest.main(), che ha reso eseguibile con il interprete Python come il driver principale:

    # pytest_test.py: 
    @profile # for line_profiler only 
    def test_example(): 
        x = 3**32 
        assert x == 1853020188851841 
    
    # for profiling with cProfile and line_profiler 
    import pytest 
    pytest.main(__file__) 
    

    Ora è possibile eseguire questo test senza py.test come il driver principale utilizzando altri strumenti:

    funzioni
    $ kernprof.py -l pytest_test.py 
    $ python -m line_profiler pytest_test.py.lprof 
    

    o

    $ python -m cProfile pytest_test.py 
    
  2. al profilo py.test-specifici come pytest_funcarg*() con line_profiler loro ho diviso in due per evitare confusione tra py.test e line_profiler:

    def pytest_funcarg__foo(request): 
        return foo(request) 
    
    @profile 
    def foo(request): 
    ... 
    

Lo stesso metodo funziona per memory_profiler.

18

Run pytest come questo:

python -m cProfile -o profile $(which py.test) 

Si può anche passare in argomenti opzionali:

python -m cProfile -o profile $(which py.test) \ 
    tests/worker/test_tasks.py -s campaigns 

Questo creerà un file binario denominato profile nella directory corrente. Questo può essere analizzato con pstats:

import pstats 
p = pstats.Stats('profile') 
p.strip_dirs() 
p.sort_stats('cumtime') 
p.print_stats(50) 

Questo stamperà le 50 linee con la durata cumulativa più lunga.

+0

Ho provato a farlo funzionare su Windows. Ma se fallisce sul primo comando, dicendo: "no tale file di directory '(quale'". Ho provato a dare il percorso assoluto al binario py.test.exe ma ottengo un errore diverso: "TypeError: compile() stringa attesa senza byte nulli. "Ho ottenuto il profiling in esecuzione aggiungendo una chiamata pytest.main nel modulo test. Qualche suggerimento su come farlo funzionare dalla riga di comando su Windows? – Kanguros

+0

Da riga di comando: importazione' 'python -c" pstats; pstats.Stats ('profile'). strip_dirs(). sort_stats ('cumtime'). print_stats (50) "' ' – jwhitlock