1
- #!/usr/bin/python
1
+ #!/usr/bin/env python2
2
+
2
3
# Copyright 2015 Google Inc
3
4
#
4
5
# Licensed under the Apache License, Version 2.0 (the "License");
14
15
# limitations under the License.
15
16
16
17
# [START runner]
17
- import optparse
18
- import os
19
- import sys
20
- import unittest
18
+ """App Engine local test runner example.
21
19
20
+ This program handles properly importing the App Engine SDK so that test modules
21
+ can use google.appengine.* APIs and the Google App Engine testbed.
22
22
23
- USAGE = """%prog SDK_PATH TEST_PATH
24
- Run unit tests for App Engine apps.
23
+ Example invocation:
25
24
26
- SDK_PATH Path to Google Cloud or Google App Engine SDK installation, usually
27
- ~/google_cloud_sdk
28
- TEST_PATH Path to package containing test modules"""
25
+ $ python runner.py ~/google-cloud-sdk
26
+ """
29
27
28
+ import argparse
29
+ import os
30
+ import sys
31
+ import unittest
30
32
31
- def append_or_insert_path (path ):
32
- """Adds GAE path to system path, or appends it to the google path
33
- if that already exists.
34
33
35
- Not all Google packages are inside namespaced packages, which means
36
- there might be another named `google` on the path, and simply appending
37
- the App Engine SDK to the path will not work since the other package
38
- will get discovered and used first. This ugly hack emulates namespace
39
- packages by first searching if a `google` package already exists by
40
- importing it, and if so appending to its path, otherwise it just
41
- inserts it into the import path by itself.
42
- """
34
+ def fixup_paths (path ):
35
+ """Adds GAE SDK path to system path and appends it to the google path
36
+ if that already exists."""
37
+ # Not all Google packages are inside namespace packages, which means
38
+ # there might be another non-namespace package named `google` already on
39
+ # the path and simply appending the App Engine SDK to the path will not
40
+ # work since the other package will get discovered and used first.
41
+ # This emulates namespace packages by first searching if a `google` package
42
+ # exists by importing it, and if so appending to its module search path.
43
43
try :
44
44
import google
45
45
google .__path__ .append ("{0}/google" .format (path ))
46
46
except ImportError :
47
- sys . path . insert ( 0 , path )
47
+ pass
48
48
49
+ sys .path .insert (0 , path )
49
50
50
- def main (sdk_path , test_path ):
51
- # If the sdk path points to a google cloud sdk installation
52
- # then we should alter it to point to the GAE platform location.
53
51
52
+ def main (sdk_path , test_path , test_pattern ):
53
+ # If the SDK path points to a Google Cloud SDK installation
54
+ # then we should alter it to point to the GAE platform location.
54
55
if os .path .exists (os .path .join (sdk_path , 'platform/google_appengine' )):
55
- append_or_insert_path (
56
- os . path . join ( sdk_path , 'platform/google_appengine' ))
57
- else :
58
- append_or_insert_path (sdk_path )
56
+ sdk_path = os . path . join ( sdk_path , 'platform/google_appengine' )
57
+
58
+ # Make sure google.appengine.* modules are importable.
59
+ fixup_paths (sdk_path )
59
60
60
- # Ensure that the google.appengine.* packages are available
61
- # in tests as well as all bundled third-party packages.
61
+ # Make sure all bundled third-party packages are available.
62
62
import dev_appserver
63
63
dev_appserver .fix_sys_path ()
64
64
@@ -69,22 +69,34 @@ def main(sdk_path, test_path):
69
69
import appengine_config
70
70
(appengine_config )
71
71
except ImportError :
72
- print " Note: unable to import appengine_config."
72
+ print ( ' Note: unable to import appengine_config.' )
73
73
74
74
# Discover and run tests.
75
- suite = unittest .loader .TestLoader ().discover (test_path , "*_test.py" )
76
- unittest .TextTestRunner (verbosity = 2 ).run (suite )
75
+ suite = unittest .loader .TestLoader ().discover (test_path , test_pattern )
76
+ return unittest .TextTestRunner (verbosity = 2 ).run (suite )
77
77
78
78
79
79
if __name__ == '__main__' :
80
- parser = optparse .OptionParser (USAGE )
81
- options , args = parser .parse_args ()
82
- if len (args ) != 2 :
83
- print 'Error: Exactly 2 arguments required.'
84
- parser .print_help ()
80
+ parser = argparse .ArgumentParser (
81
+ description = __doc__ ,
82
+ formatter_class = argparse .RawDescriptionHelpFormatter )
83
+ parser .add_argument (
84
+ 'sdk_path' ,
85
+ help = 'The path to the Google App Engine SDK or the Google Cloud SDK.' )
86
+ parser .add_argument (
87
+ '--test-path' ,
88
+ help = 'The path to look for tests, defaults to the current directory.' ,
89
+ default = os .getcwd ())
90
+ parser .add_argument (
91
+ '--test-pattern' ,
92
+ help = 'The file pattern for test modules, defaults to *_test.py.' ,
93
+ default = '*_test.py' )
94
+
95
+ args = parser .parse_args ()
96
+
97
+ result = main (args .sdk_path , args .test_path , args .test_pattern )
98
+
99
+ if not result .wasSuccessful ():
85
100
sys .exit (1 )
86
- SDK_PATH = args [0 ]
87
- TEST_PATH = args [1 ]
88
- main (SDK_PATH , TEST_PATH )
89
101
90
102
# [END runner]
0 commit comments