main.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. # -*- coding: utf-8 -*-
  2. """!@package grass.gunittest.main
  3. @brief GRASS Python testing framework module for running from command line
  4. Copyright (C) 2014 by the GRASS Development Team
  5. This program is free software under the GNU General Public
  6. License (>=v2). Read the file COPYING that comes with GRASS GIS
  7. for details.
  8. @author Vaclav Petras
  9. """
  10. import os
  11. import sys
  12. from unittest.main import TestProgram, USAGE_AS_MAIN
  13. TestProgram.USAGE = USAGE_AS_MAIN
  14. from .loader import GrassTestLoader
  15. from .runner import GrassTestRunner
  16. from .invoker import GrassTestFilesInvoker
  17. from .utils import silent_rmtree
  18. import grass.script.core as gcore
  19. class GrassTestProgram(TestProgram):
  20. """A class to be used by individual test files (wrapped in the function)"""
  21. def __init__(self, exit_at_end, grass_location, clean_outputs=True,
  22. unittest_argv=None, module=None,
  23. verbosity=1,
  24. failfast=None, catchbreak=None):
  25. """Prepares the tests in GRASS way and then runs the tests.
  26. :param bool clean_outputs: if outputs in mapset and in ?
  27. """
  28. self.test = None
  29. self.grass_location = grass_location
  30. # it is unclear what the exact behavior is in unittest
  31. # buffer stdout and stderr during tests
  32. buffer_stdout_stderr = False
  33. grass_loader = GrassTestLoader(grass_location=self.grass_location)
  34. grass_runner = GrassTestRunner(verbosity=verbosity,
  35. failfast=failfast,
  36. buffer=buffer_stdout_stderr)
  37. super(GrassTestProgram, self).__init__(module=module,
  38. argv=unittest_argv,
  39. testLoader=grass_loader,
  40. testRunner=grass_runner,
  41. exit=exit_at_end,
  42. verbosity=verbosity,
  43. failfast=failfast,
  44. catchbreak=catchbreak,
  45. buffer=buffer_stdout_stderr)
  46. def test():
  47. """Run a test of a module.
  48. """
  49. # TODO: put the link to to the report only if available
  50. # TODO: how to disable Python code coverage for module and C tests?
  51. doing_coverage = False
  52. try:
  53. import coverage
  54. doing_coverage = True
  55. cov = coverage.coverage(omit="*testsuite*")
  56. cov.start()
  57. except ImportError:
  58. pass
  59. # TODO: add some message somewhere
  60. # TODO: enable passing omit to exclude also gunittest or nothing
  61. program = GrassTestProgram(module='__main__', exit_at_end=False, grass_location='all')
  62. if doing_coverage:
  63. cov.stop()
  64. cov.html_report(directory='testcodecoverage')
  65. # TODO: is sys.exit the right thing here
  66. sys.exit(not program.result.wasSuccessful())
  67. # TODO: test or main? test looks more general
  68. # unittest has main() but doctest has testmod()
  69. main = test
  70. def discovery():
  71. """Recursively find all tests in testsuite directories and run them
  72. Everything is imported and runs in this process.
  73. Runs using::
  74. python main.py discovery [start_directory]
  75. """
  76. doing_coverage = False
  77. try:
  78. import coverage
  79. doing_coverage = True
  80. cov = coverage.coverage(omit="*testsuite*")
  81. cov.start()
  82. except ImportError:
  83. pass
  84. # TODO: add some message somewhere
  85. program = GrassTestProgram(grass_location='nc', exit_at_end=False)
  86. if doing_coverage:
  87. cov.stop()
  88. cov.html_report(directory='testcodecoverage')
  89. sys.exit(not program.result.wasSuccessful())
  90. # TODO: create a full interface (using grass parser or argparse)
  91. if __name__ == '__main__':
  92. if len(sys.argv) == 4:
  93. gisdbase = sys.argv[1]
  94. location = sys.argv[2]
  95. location_shortcut = sys.argv[3]
  96. elif len(sys.argv) == 3:
  97. location = sys.argv[1]
  98. location_shortcut = sys.argv[2]
  99. gisdbase = gcore.gisenv()['GISDBASE']
  100. else:
  101. sys.stderr.write("Usage: %s [gisdbase] location location_shortcut\n" % sys.argv[0])
  102. sys.exit(1)
  103. assert gisdbase
  104. if not os.path.exists(gisdbase):
  105. sys.stderr.write("GISDBASE <%s> does not exist\n" % gisdbase)
  106. sys.exit(1)
  107. results_dir = 'testreport'
  108. silent_rmtree(results_dir) # TODO: too brute force?
  109. invoker = GrassTestFilesInvoker(start_dir='.')
  110. invoker.run_in_location(gisdbase=gisdbase,
  111. location=location,
  112. location_shortcut=location_shortcut,
  113. results_dir=results_dir)