/functional_tests/test.py
Python | 220 lines | 185 code | 0 blank | 35 comment | 3 complexity | b2eed2a0cdd9babede707b8cdc23d5be MD5 | raw file
- """
- @brief:
- Functional tests of the feature build_xctest
- @required :
- Most of the projects use carthage to handle dependencies
- The dependencies have been built using Swift version 5.0
- The functional tests use iphone X simulator please be free to change the simulator your XCode version support
- XCode should be at least 10.2 ( to support Swift 5.0)
- Swiftlint is required to compile duckduckgo ( brew install swiftlint)
- 5 projects are tested:
- - Simple TestApp with no customScheme
- - OpenfoodFacts
- - Wikipedia with multiple schemes and target
- - Riot with multiple schemes and targets
- - DuckDuckGo use multiple XCUITests
- The projects have been zip to reduce the impact on the git repo and are automatically unzip before there are build
- We use subprocess and unzip because zipfile python lib lead to XCode build failure
- @Result:
- We correctly manage to build the source to find the product except for 3 cases :
- - There are multiple schemes and the user didn't specify one ==> MultipleSchemesError is raised
- - The product is meant to be build with a workspace instead of a project and no workspace is given
- ==> BuildFailed is raised
- - The project has multiple XCUITests and no product is given ==> MultipleXCUITestError is raised
- """
- import subprocess
- from datatheorem_api_client.xcuitest_utils import XCUITestBuilder, MultipleXCUITestError, MultipleSchemesError
- import os
- import unittest
- from unittest.mock import patch
- from contextlib import contextmanager
- import shutil
- def patched_subprocess(list_param):
- """Add a simulator destination
- Allow to build a product without signing"""
- list_param.extend(['-destination', 'platform=iOS Simulator,name=iPhone X,OS=12.2']),
- multiple_output_print('Building Sources...')
- with open(os.path.join(os.path.dirname(__file__), 'functional-tests.log'), 'a+') as log_file:
- subprocess.call(
- list_param,
- stdout=log_file,
- stderr=log_file
- )
- def multiple_output_print(output_string):
- with open(os.path.join(os.path.dirname(__file__), 'functional-tests.log'), 'a+') as log_file:
- print(output_string)
- print(output_string, file=log_file)
- class FunctionalTestBuildXctest(unittest.TestCase):
- def test_reference_app(self):
- """
- Parsing a simple TestApp
- The dt-api-client was originally tested using this app
- """
- with extract_zip_project('TestApp.zip', 'TestApp'):
- multiple_output_print('Try to Build Xcode project Test App and extracting UI testing bundle...')
- helper = XCUITestBuilder(os.path.join(os.path.dirname(__file__), "TestApp/TestApp.xcodeproj"))
- with patch.object(subprocess, 'check_output', new=patched_subprocess):
- file_to_upload, app_bundle_id, app_version = helper.build_xctest()
- multiple_output_print('Extracting xctest bundle...')
- assert "TestAppUITests.xctest.zip" in file_to_upload
- os.remove(file_to_upload)
- multiple_output_print('Test OK: TestAppUITests found')
- def test_XCBuildConfiguration_with_workspace_riot(self):
- """
- Riot use pod to handle external dependencies, pod require to build using a workspace instead of a project
- This test try the feature : create_from_xcworkspace
- Result : Success
- """
- with extract_zip_project('riot.zip', 'riot-ios-develop'):
- multiple_output_print('Try to Build Xcode Workspace Riot with specific scheme')
- helper = XCUITestBuilder.create_from_xcworkspace(
- os.path.join(os.path.dirname(__file__), "riot-ios-develop/Riot.xcodeproj"),
- os.path.join(os.path.dirname(__file__), "riot-ios-develop/Riot.xcworkspace"))
- with patch.object(subprocess, 'check_output', new=patched_subprocess):
- file_to_upload, app_bundle_id, app_version = helper.build_xctest(None, "Riot")
- multiple_output_print('Extracting xctest bundle for Scheme : Riot...')
- assert "RiotUITests.xctest.zip" in file_to_upload
- os.remove(file_to_upload)
- multiple_output_print('Test OK: RiotUITests found')
- def test_multiple_schemes_riot(self):
- """
- The riot application is a slack open source alternative
- The project use 3 schemes Riot RiotShareExtension and SiriIntents
- We can see on Xcode that the last two are sub of Riot
- So we should be able to automatically determine the correct scheme
- Result : MultipleSchemesError
- """
- with extract_zip_project('riot.zip', 'riot-ios-develop'):
- multiple_output_print('Try to determine scheme and Build Xcode project Riot')
- helper = XCUITestBuilder(os.path.join(os.path.dirname(__file__), "riot-ios-develop/Riot.xcodeproj"))
- self.assertRaises(MultipleSchemesError, helper.build_xctest)
- multiple_output_print('Test OK: MultipleSchemesError raised')
- def test_multiple_scheme_wikipedia(self):
- """
- The project find the correct product name : WikipediaUITests
- But we can't determine for sure the scheme for this project
- Result : MultipleSchemesError
- """
- with extract_zip_project('wikipedia.zip', 'wikipedia-ios-develop'):
- multiple_output_print('Try to determine scheme and Build Xcode project Wikipedia')
- helper = XCUITestBuilder(
- os.path.join(os.path.dirname(__file__), "wikipedia-ios-develop/Wikipedia.xcodeproj"))
- self.assertRaises(MultipleSchemesError, helper.build_xctest)
- multiple_output_print('Test OK: MultipleSchemesError raised')
- def test_XCBuildConfiguration_multiple_target_wikipedia(self):
- """
- If we specify the scheme, the project is correctly build
- Result : Success
- """
- with extract_zip_project('wikipedia.zip', 'wikipedia-ios-develop'):
- multiple_output_print('Try to determine target and Build Xcode project Wikipedia')
- helper = XCUITestBuilder(
- os.path.join(os.path.dirname(__file__), "wikipedia-ios-develop/Wikipedia.xcodeproj"))
- with patch.object(subprocess, 'check_output', new=patched_subprocess):
- file_to_upload, app_bundle_id, app_version = helper.build_xctest(None, "WikipediaUITests")
- multiple_output_print('Extracting xctest bundle for Scheme : WikipediaUITests...')
- assert "WikipediaUITests.xctest.zip" in file_to_upload
- os.remove(file_to_upload)
- multiple_output_print('Test OK: WikipediaUITests found')
- def test_simple_project_open_food_fact(self):
- """
- The project find the correct target but it don't manage to determine the scheme
- Result : MultipleSchemesError
- """
- with extract_zip_project('openfoodfacts.zip', 'openfoodfacts-ios-master'):
- multiple_output_print('Building Xcode project openfoodfacts App and extracting UI testing bundle...')
- helper = XCUITestBuilder(
- os.path.join(os.path.dirname(__file__), 'openfoodfacts-ios-master/OpenFoodFacts.xcodeproj'))
- self.assertRaises(MultipleSchemesError, helper.build_xctest)
- multiple_output_print('Test OK: MultipleSchemesError raised')
- def test_multiple_product_duck_duck_go(self):
- """
- The project duckduckgo has multiple XCUITests
- We need to specify the scheme and the product to correctly build XCUITest
- Result : MultipleXCUITestError
- """
- with extract_zip_project('duckduckgo.zip', 'duckduckgo'):
- multiple_output_print('Try to Build Xcode project duckduckgo App and extracting UI testing bundle...')
- helper = XCUITestBuilder(os.path.join(os.path.dirname(__file__), 'duckduckgo/DuckDuckGo.xcodeproj'))
- multiple_output_print('Extracting xctest bundle for Scheme : DuckDuckGo...')
- self.assertRaises(MultipleXCUITestError, helper.build_xctest, None, "DuckDuckGo")
- multiple_output_print('Test OK: MultipleXCUITestError raised')
- def test_specify_product_scheme_duck_duck_go(self):
- """
- The project duckduckgo has multiple XCUITests
- We need to specify the scheme And the product to correctly build the XCUITest
- Result : Success
- """
- with extract_zip_project('duckduckgo.zip', 'duckduckgo'):
- multiple_output_print('Try to Build Xcode project duckduckgo App and extracting UI testing bundle...')
- helper = XCUITestBuilder(os.path.join(os.path.dirname(__file__), 'duckduckgo/DuckDuckGo.xcodeproj'))
- with patch.object(subprocess, 'check_output', new=patched_subprocess):
- file_to_upload, app_bundle_id, app_version = helper.build_xctest("DuckDuckGoUITests", "DuckDuckGo")
- multiple_output_print('Extracting xctest bundle for product DuckDuckGoUITests and for Scheme : DuckDuckGo...')
- assert "DuckDuckGoUITests.xctest.zip" in file_to_upload
- os.remove(file_to_upload)
- multiple_output_print('Test OK: DuckDuckGoUITests found')
- @contextmanager
- def extract_zip_project(zip_name, root_dir):
- try:
- multiple_output_print(f'\nExtracting {zip_name} to folder {root_dir}')
- with open(os.devnull, 'w') as none_file:
- subprocess.call([
- 'unzip', os.path.join(os.path.dirname(__file__), zip_name),
- '-d', os.path.dirname(__file__)
- ],
- stdout=none_file
- )
- yield
- finally:
- shutil.rmtree(os.path.join(os.path.dirname(__file__), root_dir))
- shutil.rmtree(os.path.join(os.path.dirname(__file__), "__MACOSX"))
- if __name__ == '__main__':
- # Create an empty file full_stack_trace containing all the build step
- with open(os.path.join(os.path.dirname(__file__), 'functional-tests.log'), 'w'):
- pass
- unittest.main()