PageRenderTime 51ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/functional_tests/test.py

https://bitbucket.org/datatheorem/dt-api-client
Python | 220 lines | 185 code | 0 blank | 35 comment | 3 complexity | b2eed2a0cdd9babede707b8cdc23d5be MD5 | raw file
  1. """
  2. @brief:
  3. Functional tests of the feature build_xctest
  4. @required :
  5. Most of the projects use carthage to handle dependencies
  6. The dependencies have been built using Swift version 5.0
  7. The functional tests use iphone X simulator please be free to change the simulator your XCode version support
  8. XCode should be at least 10.2 ( to support Swift 5.0)
  9. Swiftlint is required to compile duckduckgo ( brew install swiftlint)
  10. 5 projects are tested:
  11. - Simple TestApp with no customScheme
  12. - OpenfoodFacts
  13. - Wikipedia with multiple schemes and target
  14. - Riot with multiple schemes and targets
  15. - DuckDuckGo use multiple XCUITests
  16. The projects have been zip to reduce the impact on the git repo and are automatically unzip before there are build
  17. We use subprocess and unzip because zipfile python lib lead to XCode build failure
  18. @Result:
  19. We correctly manage to build the source to find the product except for 3 cases :
  20. - There are multiple schemes and the user didn't specify one ==> MultipleSchemesError is raised
  21. - The product is meant to be build with a workspace instead of a project and no workspace is given
  22. ==> BuildFailed is raised
  23. - The project has multiple XCUITests and no product is given ==> MultipleXCUITestError is raised
  24. """
  25. import subprocess
  26. from datatheorem_api_client.xcuitest_utils import XCUITestBuilder, MultipleXCUITestError, MultipleSchemesError
  27. import os
  28. import unittest
  29. from unittest.mock import patch
  30. from contextlib import contextmanager
  31. import shutil
  32. def patched_subprocess(list_param):
  33. """Add a simulator destination
  34. Allow to build a product without signing"""
  35. list_param.extend(['-destination', 'platform=iOS Simulator,name=iPhone X,OS=12.2']),
  36. multiple_output_print('Building Sources...')
  37. with open(os.path.join(os.path.dirname(__file__), 'functional-tests.log'), 'a+') as log_file:
  38. subprocess.call(
  39. list_param,
  40. stdout=log_file,
  41. stderr=log_file
  42. )
  43. def multiple_output_print(output_string):
  44. with open(os.path.join(os.path.dirname(__file__), 'functional-tests.log'), 'a+') as log_file:
  45. print(output_string)
  46. print(output_string, file=log_file)
  47. class FunctionalTestBuildXctest(unittest.TestCase):
  48. def test_reference_app(self):
  49. """
  50. Parsing a simple TestApp
  51. The dt-api-client was originally tested using this app
  52. """
  53. with extract_zip_project('TestApp.zip', 'TestApp'):
  54. multiple_output_print('Try to Build Xcode project Test App and extracting UI testing bundle...')
  55. helper = XCUITestBuilder(os.path.join(os.path.dirname(__file__), "TestApp/TestApp.xcodeproj"))
  56. with patch.object(subprocess, 'check_output', new=patched_subprocess):
  57. file_to_upload, app_bundle_id, app_version = helper.build_xctest()
  58. multiple_output_print('Extracting xctest bundle...')
  59. assert "TestAppUITests.xctest.zip" in file_to_upload
  60. os.remove(file_to_upload)
  61. multiple_output_print('Test OK: TestAppUITests found')
  62. def test_XCBuildConfiguration_with_workspace_riot(self):
  63. """
  64. Riot use pod to handle external dependencies, pod require to build using a workspace instead of a project
  65. This test try the feature : create_from_xcworkspace
  66. Result : Success
  67. """
  68. with extract_zip_project('riot.zip', 'riot-ios-develop'):
  69. multiple_output_print('Try to Build Xcode Workspace Riot with specific scheme')
  70. helper = XCUITestBuilder.create_from_xcworkspace(
  71. os.path.join(os.path.dirname(__file__), "riot-ios-develop/Riot.xcodeproj"),
  72. os.path.join(os.path.dirname(__file__), "riot-ios-develop/Riot.xcworkspace"))
  73. with patch.object(subprocess, 'check_output', new=patched_subprocess):
  74. file_to_upload, app_bundle_id, app_version = helper.build_xctest(None, "Riot")
  75. multiple_output_print('Extracting xctest bundle for Scheme : Riot...')
  76. assert "RiotUITests.xctest.zip" in file_to_upload
  77. os.remove(file_to_upload)
  78. multiple_output_print('Test OK: RiotUITests found')
  79. def test_multiple_schemes_riot(self):
  80. """
  81. The riot application is a slack open source alternative
  82. The project use 3 schemes Riot RiotShareExtension and SiriIntents
  83. We can see on Xcode that the last two are sub of Riot
  84. So we should be able to automatically determine the correct scheme
  85. Result : MultipleSchemesError
  86. """
  87. with extract_zip_project('riot.zip', 'riot-ios-develop'):
  88. multiple_output_print('Try to determine scheme and Build Xcode project Riot')
  89. helper = XCUITestBuilder(os.path.join(os.path.dirname(__file__), "riot-ios-develop/Riot.xcodeproj"))
  90. self.assertRaises(MultipleSchemesError, helper.build_xctest)
  91. multiple_output_print('Test OK: MultipleSchemesError raised')
  92. def test_multiple_scheme_wikipedia(self):
  93. """
  94. The project find the correct product name : WikipediaUITests
  95. But we can't determine for sure the scheme for this project
  96. Result : MultipleSchemesError
  97. """
  98. with extract_zip_project('wikipedia.zip', 'wikipedia-ios-develop'):
  99. multiple_output_print('Try to determine scheme and Build Xcode project Wikipedia')
  100. helper = XCUITestBuilder(
  101. os.path.join(os.path.dirname(__file__), "wikipedia-ios-develop/Wikipedia.xcodeproj"))
  102. self.assertRaises(MultipleSchemesError, helper.build_xctest)
  103. multiple_output_print('Test OK: MultipleSchemesError raised')
  104. def test_XCBuildConfiguration_multiple_target_wikipedia(self):
  105. """
  106. If we specify the scheme, the project is correctly build
  107. Result : Success
  108. """
  109. with extract_zip_project('wikipedia.zip', 'wikipedia-ios-develop'):
  110. multiple_output_print('Try to determine target and Build Xcode project Wikipedia')
  111. helper = XCUITestBuilder(
  112. os.path.join(os.path.dirname(__file__), "wikipedia-ios-develop/Wikipedia.xcodeproj"))
  113. with patch.object(subprocess, 'check_output', new=patched_subprocess):
  114. file_to_upload, app_bundle_id, app_version = helper.build_xctest(None, "WikipediaUITests")
  115. multiple_output_print('Extracting xctest bundle for Scheme : WikipediaUITests...')
  116. assert "WikipediaUITests.xctest.zip" in file_to_upload
  117. os.remove(file_to_upload)
  118. multiple_output_print('Test OK: WikipediaUITests found')
  119. def test_simple_project_open_food_fact(self):
  120. """
  121. The project find the correct target but it don't manage to determine the scheme
  122. Result : MultipleSchemesError
  123. """
  124. with extract_zip_project('openfoodfacts.zip', 'openfoodfacts-ios-master'):
  125. multiple_output_print('Building Xcode project openfoodfacts App and extracting UI testing bundle...')
  126. helper = XCUITestBuilder(
  127. os.path.join(os.path.dirname(__file__), 'openfoodfacts-ios-master/OpenFoodFacts.xcodeproj'))
  128. self.assertRaises(MultipleSchemesError, helper.build_xctest)
  129. multiple_output_print('Test OK: MultipleSchemesError raised')
  130. def test_multiple_product_duck_duck_go(self):
  131. """
  132. The project duckduckgo has multiple XCUITests
  133. We need to specify the scheme and the product to correctly build XCUITest
  134. Result : MultipleXCUITestError
  135. """
  136. with extract_zip_project('duckduckgo.zip', 'duckduckgo'):
  137. multiple_output_print('Try to Build Xcode project duckduckgo App and extracting UI testing bundle...')
  138. helper = XCUITestBuilder(os.path.join(os.path.dirname(__file__), 'duckduckgo/DuckDuckGo.xcodeproj'))
  139. multiple_output_print('Extracting xctest bundle for Scheme : DuckDuckGo...')
  140. self.assertRaises(MultipleXCUITestError, helper.build_xctest, None, "DuckDuckGo")
  141. multiple_output_print('Test OK: MultipleXCUITestError raised')
  142. def test_specify_product_scheme_duck_duck_go(self):
  143. """
  144. The project duckduckgo has multiple XCUITests
  145. We need to specify the scheme And the product to correctly build the XCUITest
  146. Result : Success
  147. """
  148. with extract_zip_project('duckduckgo.zip', 'duckduckgo'):
  149. multiple_output_print('Try to Build Xcode project duckduckgo App and extracting UI testing bundle...')
  150. helper = XCUITestBuilder(os.path.join(os.path.dirname(__file__), 'duckduckgo/DuckDuckGo.xcodeproj'))
  151. with patch.object(subprocess, 'check_output', new=patched_subprocess):
  152. file_to_upload, app_bundle_id, app_version = helper.build_xctest("DuckDuckGoUITests", "DuckDuckGo")
  153. multiple_output_print('Extracting xctest bundle for product DuckDuckGoUITests and for Scheme : DuckDuckGo...')
  154. assert "DuckDuckGoUITests.xctest.zip" in file_to_upload
  155. os.remove(file_to_upload)
  156. multiple_output_print('Test OK: DuckDuckGoUITests found')
  157. @contextmanager
  158. def extract_zip_project(zip_name, root_dir):
  159. try:
  160. multiple_output_print(f'\nExtracting {zip_name} to folder {root_dir}')
  161. with open(os.devnull, 'w') as none_file:
  162. subprocess.call([
  163. 'unzip', os.path.join(os.path.dirname(__file__), zip_name),
  164. '-d', os.path.dirname(__file__)
  165. ],
  166. stdout=none_file
  167. )
  168. yield
  169. finally:
  170. shutil.rmtree(os.path.join(os.path.dirname(__file__), root_dir))
  171. shutil.rmtree(os.path.join(os.path.dirname(__file__), "__MACOSX"))
  172. if __name__ == '__main__':
  173. # Create an empty file full_stack_trace containing all the build step
  174. with open(os.path.join(os.path.dirname(__file__), 'functional-tests.log'), 'w'):
  175. pass
  176. unittest.main()