pythonpython-unittestline-profiler

Can I run line_profiler on python module?


I have a module named my_module with the following structure.

.
└── my_module
    ├── main.py
    └── test.py

Here, I use python -m my_module.test, in order to run the test because it uses relative import.

Then how can I run line_profiler, memory_profiler on a module? (it can be pytest)

Followings are what I have tried

1st approach

python -m cProfile -m my_module.test   # works -> but I want line_profiler

2nd approach

import line_profiler
import unittest

profiler = line_profiler.LineProfiler()

class PageTester(unittest.TestCase):
  @profiler
  def test_abc(self):
    print(1)

if __name__ == "__main__"
  unittest.main(module='page.test')
  profiler.print_stats()           # doesn't print anything

Solution

  • You can use line_profiler with unittest.TestCase. Just move the print_stats to tearDownClass of the TestCase

    import unittest
    import line_profiler
    
    profiler = line_profiler.LineProfiler()
    
    class PageTester(unittest.TestCase):
      @profiler
      def test_abc(self):
          print("abc")
          #profiler.print_stats() 
      
      @profiler
      def test_def(self):
          self.test_abc()
    
      @classmethod
      def tearDownClass(cls):  
         profiler.print_stats() 
          
    if __name__ == "__main__":
      unittest.main(module='page.test')
    

    The output is what is expected:

    abc
    abc
    Timer unit: 1e-06 s
    
    Total time: 1.3e-05 s
    File: /root/page/test.py
    Function: test_abc at line 10
    
    Line #      Hits         Time  Per Hit   % Time  Line Contents
    ==============================================================
        10                                             @profiler
        11                                             def test_abc(self):
        12         2         13.0      6.5    100.0        print("abc")
    
    Total time: 9e-06 s
    File: /root/page/test.py
    Function: test_def at line 15
    
    Line #      Hits         Time  Per Hit   % Time  Line Contents
    ==============================================================
        15                                             @profiler
        16                                             def test_def(self):
        17         1          9.0      9.0    100.0        self.test_abc()