mirror of
https://github.com/Project-Redacted/Highscores-Server.git
synced 2025-05-19 01:44:54 +00:00
Add example Unity Project
This commit is contained in:
parent
fda7ff28dd
commit
e3acdb9d6b
7122 changed files with 505543 additions and 2 deletions
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"timestamp": 1643835306,
|
||||
"signature": "JEZ8cI0UR8olyhs0OadQ+d4uKTBE29sMAde+Hboe1joVI+oEVy1uUsmZxHNYLlFqLDqZ0azsVrRO+VIe10yF2aWzU28SE86knPq7oON0fpHdnOoiolf9PTHmbatLjpyw+/zW3ZmA1tKlkjvcHm5SRP1SSSaKimsHKhgVELaUReHulvYlTtjV1alFTwNmZjFKfLGv+j2SsRrSb93zSKsKyzUc+809b+GgV0oWgtnrAFUsMjVhNgoTzHUJif53u5TltguAXEmJjseWZcxUNqrfx3lR0MshymoUUlxHVp64eOmBXREa74B7lboyyL/uaVzcSO36PfcElOFti6hATf6LFhSCzIOXJ5tQjF7+GzViVNtMLHEPVDtfMt4LQAy5fVTjEdSstnzTN2RjTys1lJB6JvLJNZcreuRLd80xHkcSuGH5yEZZOn+Od264urnb6FWQ7ajYdLa3+LNlVRgrh9EwbgWbx9ApNxT9qzvG8vprC5V6IeL3QKf9vsyc7p7NuT3D",
|
||||
"publicKey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQm9qQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FZOEFNSUlCaWdLQ0FZRUFzdUhXYUhsZ0I1cVF4ZEJjTlJKSAordHR4SmoxcVY1NTdvMlZaRE1XaXhYRVBkRTBEMVFkT1JIRXNSS1RscmplUXlERU83ZlNQS0ZwZ1A3MU5TTnJCCkFHM2NFSU45aHNQVDhOVmllZmdWem5QTkVMenFkVmdEbFhpb2VpUnV6OERKWFgvblpmU1JWKytwbk9ySTRibG4KS0twelJlNW14OTc1SjhxZ1FvRktKT0NNRlpHdkJMR2MxSzZZaEIzOHJFODZCZzgzbUovWjBEYkVmQjBxZm13cgo2ZDVFUXFsd0E5Y3JZT1YyV1VpWXprSnBLNmJZNzRZNmM1TmpBcEFKeGNiaTFOaDlRVEhUcU44N0ZtMDF0R1ZwCjVNd1pXSWZuYVRUemEvTGZLelR5U0pka0tldEZMVGdkYXpMYlpzUEE2aHBSK0FJRTJhc0tLTi84UUk1N3UzU2cKL2xyMnZKS1IvU2l5eEN1Q20vQWJkYnJMbXk0WjlSdm1jMGdpclA4T0lLQWxBRWZ2TzV5Z2hSKy8vd1RpTFlzUQp1SllDM0V2UE16ZGdKUzdGR2FscnFLZzlPTCsxVzROY05yNWdveVdSUUJ0cktKaWlTZEJVWmVxb0RvSUY5NHpCCndGbzJJT1JFdXFqcU51M3diMWZIM3p1dGdtalFra3IxVjJhd3hmcExLWlROQWdNQkFBRT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg"
|
||||
}
|
|
@ -0,0 +1,250 @@
|
|||
# Changelog
|
||||
## [1.1.31] - 2022-02-03
|
||||
- Fixed "Open source code" on tests when located inside a package.
|
||||
- Added editor analytics events.
|
||||
- Added `buildPlayerPath` argument. Path to where built player with tests is saved.
|
||||
|
||||
## [1.1.30] - 2021-10-15
|
||||
- Added validation of IEnumerator return type for parameterized tests with UnityTest attribute (DSTP-743).
|
||||
- Fixed runInBackground reset to original value after finishing to run playmode tests (DSTR-248).
|
||||
- Fixed issue with circular assembly references when constructing the test tree (DSTR-300).
|
||||
|
||||
## [1.1.29] - 2021-08-12
|
||||
- Nested enumerator execution order fix (DSTR-227).
|
||||
- Fix UI not running any tests if run select on a nested namespaces (DSTR-256).
|
||||
|
||||
## [1.1.28] - 2021-06-25
|
||||
- Fix CountDownEvent reference due to `com.unity.ext.nunit` update.
|
||||
- Various performance optimization to fix "Test execution timed out. No activity received from the player in 600 seconds."(DSTR-100).
|
||||
|
||||
## [1.1.27] - 2021-06-15
|
||||
- Fix empty reason on passed tests results xml (DSTR-63)
|
||||
- Fix Repeat and Retry attribute for UnityTest in PlayMode (DSTR-237).
|
||||
- Remove XDK Xbox One platform after Unity 2020.3
|
||||
- Fixed issue when `.` suffix was applied to BuildTargets without extension.
|
||||
- Added support for `GameCoreXboxOne` and `GameCoreXboxSeries` reduced location path length.
|
||||
|
||||
## [1.1.26] - 2021-05-25
|
||||
- Fix html bug in TestRunnerApi API code snippet (DS-1973).
|
||||
- Fix typo bug in PreBuildSetup code example (DS-1974).
|
||||
- Fix incorrect syntax in command line reference (DS-1971).
|
||||
- Fixed a bug where test filter would match project or player path (DSTP-412).
|
||||
- Added playerGraphicsAPI TestSettings parameter
|
||||
|
||||
## [1.1.25] - 2021-05-05
|
||||
- Fixed a bug where test filter would match project or player path (DSTP-412).
|
||||
- Added playerGraphicsAPI TestSettings parameter
|
||||
|
||||
## [1.1.24] - 2021-03-04
|
||||
- Improving UTF documentation(DSTR-120)
|
||||
- Updated "Actions outside of tests" section of user manual. Added flow charts to clarify execution order for SetUp/TearDown, TestActions, and complete flow (DSTR-121).
|
||||
- Fixed accepted values for scriptingBackend argument to be string literals instead of int values (DSTR-122).
|
||||
- Fixed possible values of ResultState to be Passed, Failed, Skipped, Inconclusive, plus labels instead of Success and Failure (DSTR-125).
|
||||
- Added NUNit version information (DSTR-130).
|
||||
- Added namespace information for LogAsset in user manual (DSTR-124).
|
||||
- Added instructions for creating additional sets of tests (DSTR-129).
|
||||
- Added information on testResults XML output format and exit codes (DSTR-131).
|
||||
- Updated description of testPlatform command line argument to clarify accepted values and their meaning (DSTR-123).
|
||||
- Reduce time taken by filtering operations when only a subset of tests is run.
|
||||
- Reduced the time taken to rebuild the test tree and to scan for assets a test created but did not delete.
|
||||
- Reduce the per-test overhead of running tests in the editor.
|
||||
- Added profiler markers around test setup, teardown, and execution.
|
||||
- Fixed unstable timeout bug (DSTR-21).
|
||||
|
||||
## [1.1.23] - 2021-01-21
|
||||
- Improving UTF documentation(DSTR-120)
|
||||
- Updated "Actions outside of tests" section of user manual. Added flow charts to clarify execution order for SetUp/TearDown, TestActions, and complete flow (DSTR-121).
|
||||
- Fixed accepted values for scriptingBackend argument to be string literals instead of int values (DSTR-122).
|
||||
- Fixed possible values of ResultState to be Passed, Failed, Skipped, Inconclusive, plus labels instead of Success and Failure (DSTR-125).
|
||||
- Added NUNit version information (DSTR-130).
|
||||
- Added namespace information for LogAsset in user manual (DSTR-124).
|
||||
- Added instructions for creating additional sets of tests (DSTR-129).
|
||||
- Added information on testResults XML output format and exit codes (DSTR-131).
|
||||
- Updated description of testPlatform command line argument to clarify accepted values and their meaning (DSTR-123).
|
||||
|
||||
## [1.1.22] - 2021-01-21
|
||||
- Fixed issue where test result of an explicit test was set to skipped in case it was passing and running from command line with testfilter set to the explicit test (DS-1236).
|
||||
- Fixed an issue where tests located in assemblies that did not directly reference any test assemblies were not included (DSTR-30).
|
||||
- Fixed an issue where UnitySetup methods were incorrectly being rerun when entering playmode, rather than being skipped (DSTR-68).
|
||||
- Internal: Remove ##utp message AssemblyCompilationErrors (DS-1277)
|
||||
- Fixed issue where if the timeout was exceeded in SetUp the timeout exception was not thrown(DSTR-21).
|
||||
- Removed ability to `Enable playmode tests for all assemblies` from the TestRunner UI, since it is a deprecated behavior. It enforces to use of assembly definition files (DSTR-45).
|
||||
- Fixed typo in `LogAssert.cs` documentation.
|
||||
|
||||
## [1.1.21] - 2020-12-04
|
||||
- Fixed issue where test result of an explicit test was set to skipped in case it was passing and running from command line with testfilter set to the explicit test (DS-1236).
|
||||
- Fixed an issue where tests located in assemblies that did not directly reference any test assemblies were not included (DSTR-30).
|
||||
- Fixed an issue where UnitySetup methods were incorrectly being rerun when entering playmode, rather than being skipped (DSTR-68).
|
||||
- Internal: Remove ##utp message AssemblyCompilationErrors (ds-1277)
|
||||
- Fixed issue where if the timeout was exceeded in SetUp the timeout exception was not thrown(DSTR-21).
|
||||
- Removed ability to `Enable playmode tests for all assemblies` from the TestRunner UI, since it is a deprecated behavior. It enforces to use of assembly definition files (DSTR-45).
|
||||
|
||||
## [1.1.20] - 2020-12-04
|
||||
- The logscope is now available in OneTimeTearDown.
|
||||
- Fixed an issue where failing tests would not result in the correct exit code if a domain reload happens after the test has run (DS-1304).
|
||||
- If a player build fails, the test specific build settings should be cleaned up and the original values restored as intended (DS-1001).
|
||||
- Added better error message when using TestRunCallbackAttribute and the implementation is stripped away (DS-454).
|
||||
- Fixed an issue where the test results xml would have a zero end-time for tests executed before a domain reload (DSTR-63).
|
||||
- Fixed OpenSource in case of a Test in a nested class (DSTR-6)
|
||||
- UnityTests with a domain reload now works correctly in combination with Retry and Repeat attributes (DS-428).
|
||||
- Fixed OpenSource in case of Tests located inside a package (DS-432)
|
||||
|
||||
## [1.1.19] - 2020-11-17
|
||||
- Command line runs with an inconclusive test result now exit with exit code 2 (case DS-951).
|
||||
- Fixed timeout during UnitySetUp which caoused test to pass instead of failing due to wrong time format.
|
||||
- Timeout exeption thrown when timeout time is exeded in the UnitySetup when using `WaitForSeconds(n)`.
|
||||
- Updating `com.unity.ext.nunit` version
|
||||
- Method marked with UnityTest that are not returning IEnumerator is now giving a proper error (DS-1059).
|
||||
|
||||
## [1.1.18] - 2020-10-07
|
||||
- Fixed issue of timeout during UnitySetUp which wasn't detected and allowed the test to pass instead of failing (case DSTR-21)
|
||||
|
||||
## [1.1.17] - 2020-10-05
|
||||
- Fixed an issue where the WaitForDomainReload yield instruction would sometimes let the test continue for one frame before the domain reload.
|
||||
- Added support for negation in filters using !. E.g. !CategoryToExclude.
|
||||
- Fixed an issue where if the first test enters PlayMode from UnitySetup then the test body will not run on consecutive runs (case 1260901).
|
||||
- Clear Results button clears the test results in the GUI (DSTR-16)
|
||||
- Improved UI in Test Runner window, added new options:
|
||||
- Run Selected Tests in player
|
||||
- Build/Export project with all tests in player
|
||||
- Build/Export project with selected tests in player
|
||||
- Fixed issue on loading EditMode or Playmode test tree in the wrong tab when switching between tabs when TestRunner is loading (DS-865)
|
||||
|
||||
## [1.1.16] - 2020-07-09
|
||||
- Follow up on fix when UTF picks up on outdated compilation errors
|
||||
|
||||
## [1.1.15] - 2020-07-02
|
||||
- Fixed an issue where an exception is thrown on getting the enumerator of a UnityTest would result in stopping the test run instead of failing it (case 1212000).
|
||||
- Including a trailing semi-colon in a testName filter no longer results in all tests being run (case 1171200).
|
||||
- Fixed and issue when Unity Test Framework exits editor on an outdated script compilation error (during api updates)
|
||||
|
||||
## [1.1.14] - 2020-04-03
|
||||
- Added the 'assemblyNames' command line argument for filtering on the assembly level.
|
||||
- The dll and project level of the tree view should now correctly show the results when running tests in a player (case 1197026).
|
||||
- Optimize usage of player connection when transfering test results (case 1229200).
|
||||
- Ignore internal test framework tests assertions (case 1206961).
|
||||
|
||||
## [1.1.13] - 2020-03-16
|
||||
- Fixed an issue where a combination of Entering / Exiting playmode and recompiling scripts would result in the test run repeating (case 1213958).
|
||||
- Fixed a regression from 1.1.12 where prefabs left in the scene would be cleaned up to aggressively.
|
||||
- Fixed Test execution timed out. No activity received from the player in 600 seconds error when player is not supposed to start (case 1225147)
|
||||
|
||||
## [1.1.12] - 2020-03-02
|
||||
- Now 'Open error line' for a failed UTF test does not throw exceptions for corrupted testable pdb in Editor release mode (case 1118259)
|
||||
- Fixed an issue where running a test fixture would also run other fixtures with the same full name (namespace plus classname) in other assemblies (case 1197385).
|
||||
- Running tests with the same full name, with a domain reload inbetween, will no longer fail to initialize the fixture of the second class (case 1205240).
|
||||
- Running a playmode tests with "Maximize on Play" will now correctly show the result of the tests in the test runner window (case 1014908).
|
||||
- Fixed an issue where leaving a game object in a scene with a DontSaveInEditor hideFlags would result in an error on cleanup (case 1136883).
|
||||
- Now ITestPlayerBuildModifier.ModifyOptions is called as expected when running tests on a device (case 1213845)
|
||||
|
||||
## [1.1.11] - 2020-01-16
|
||||
- Fixed test runner dlls got included into player build (case 1211624)
|
||||
- Passing a non-full-path of XML file for -testResults in Unity Batchmode issue resolved, now passing "result.xml" creates the result file in the project file directory (case 959078)
|
||||
- Respect Script Debugging build setting when running tests
|
||||
|
||||
## [1.1.10] - 2019-12-19
|
||||
- Introduced PostSuccessfulLaunchAction callback
|
||||
- Fixed an issue where canceling a UnityTest while it was running would incorrectly mark it as passed instead of canceled.
|
||||
- Added command line argument for running tests synchronously.
|
||||
- The test search bar now handles null values correctly.
|
||||
- The test output pane now retains its size on domain reloads.
|
||||
|
||||
## [1.1.9] - 2019-12-12
|
||||
- Rolled back refactoring to the test run system, as it caused issues in some corner cases.
|
||||
|
||||
## [1.1.8] - 2019-11-15
|
||||
- Ensured that a resumed test run is continued instantly.
|
||||
|
||||
## [1.1.7] - 2019-11-14
|
||||
- Fixed an issue with test runs after domain reload.
|
||||
|
||||
## [1.1.6] - 2019-11-12
|
||||
- Building a player for test will no longer look in unrelated assemblies for relevant attributes.
|
||||
|
||||
## [1.1.5] - 2019-10-23
|
||||
- Fixed a regression to synchronous runs introduced in 1.1.4.
|
||||
|
||||
## [1.1.4] - 2019-10-15
|
||||
- Running tests in batch mode now correctly returns error code 3 (RunError) when a timeout or a build error occurs.
|
||||
- Fixed an issue where a test run in a player would time out, if the player takes longer than 10 minutes to run.
|
||||
- Added command line argument and api setting for specifying custom heartbeat timeout for running on players.
|
||||
|
||||
## [1.1.3] - 2019-09-23
|
||||
- Fixed a regression where tests in a player would report a timeout after a test run is finished.
|
||||
- Made it possible for the ui to change its test items when the test tree changes without script compilation.
|
||||
- Added synchronous runs as an option to the TestRunnerApi.
|
||||
|
||||
## [1.1.2] - 2019-09-11
|
||||
- Fixed an issue where Run Selected would run all tests in the category, if a category filter was selected, regardless of what tests were selected.
|
||||
- Unsupported attributes used in UnityTests now give an explicit error.
|
||||
- Added support for the Repeat and Retry attributes in UnityTests (case 1131940).
|
||||
- Tests with a explicit timeout higher than 10 minutes, no longer times out after running longer than 10 minutes when running from command line (case 1125991).
|
||||
- Fixed a performance regression in the test runner api result reporting, introduced in 2018.3 (case 1109865).
|
||||
- Fixed an issue where parameterized test fixtures would not run if selected in the test tree (case 1092244).
|
||||
- Pressing Clear Results now also correctly clears the counters on the test list (case 1181763).
|
||||
- Prebuild setup now handles errors logged with Debug.LogError and stops the run if any is logged (case 1115240). It now also supports LogAssert.Expect.
|
||||
|
||||
## [1.1.1] - 2019-08-07
|
||||
- Tests retrieved as a test list with the test runner api incorrectly showed both mode as their TestMode.
|
||||
- Fixed a compatibility issue with running tests from rider.
|
||||
|
||||
## [1.1.0] - 2019-07-30
|
||||
- Introduced the TestRunnerApi for running tests programmatically from elsewhere inside the Editor.
|
||||
- Introduced yield instructions for recompiling scripts and awaiting a domain reload in Edit Mode tests.
|
||||
- Added a button to the Test Runner UI for clearing the results.
|
||||
|
||||
## [1.0.18] - 2019-07-15
|
||||
- Included new full documentation of the test framework.
|
||||
|
||||
## [1.0.17] - 2019-07-11
|
||||
- Fixed an issue where the Test Runner window wouldn’t frame selected items after search filter is cleared.
|
||||
- Fixed a regression where playmode test application on the IOS platform would not quit after the tests are done.
|
||||
|
||||
## [1.0.16] - 2019-06-20
|
||||
- Fixed an issue where the Test Runner window popped out if it was docked, or if something else was docked next to it, when re-opened (case 1158961)
|
||||
- Fixed a regression where the running standalone playmode tests from the ui would result in an error.
|
||||
|
||||
## [1.0.15] - 2019-06-18
|
||||
- Added new `[TestMustExpectAllLogs]` attribute, which automatically does `LogAssert.NoUnexpectedReceived()` at the end of affected tests. See docs for this attribute for more info on usage.
|
||||
- Fixed a regression where no tests would be run if multiple filters are specified. E.g. selecting both a whole assembly and an individual test in the ui.
|
||||
- Fixed an issue where performing `Run Selected` on a selected assembly would run all assemblies.
|
||||
- Introduced the capability to do a split build and run, when running playmode tests on standalone devices.
|
||||
- Fixed an error in ConditionalIgnore, if the condition were not set.
|
||||
|
||||
## [1.0.14] - 2019-05-27
|
||||
- Fixed issue preventing scene creation in IPrebuildSetup.Setup callback when running standalone playmode tests.
|
||||
- Fixed an issue where test assemblies would sometimes not be ordered alphabetically.
|
||||
- Added module references to the package for the required modules: imgui and jsonserialize.
|
||||
- Added a ConditionalIgnore attribute to help ignoring tests only under specific conditions.
|
||||
- Fixed a typo in the player test window (case 1148671).
|
||||
|
||||
## [1.0.13] - 2019-05-07
|
||||
- Fixed a regression where results from the player would no longer update correctly in the UI (case 1151147).
|
||||
|
||||
## [1.0.12] - 2019-04-16
|
||||
- Added specific unity release to the package information.
|
||||
|
||||
## [1.0.11] - 2019-04-10
|
||||
- Fixed a regression from 1.0.10 where test-started events were triggered multiple times after a domain reload.
|
||||
|
||||
## [1.0.10] - 2019-04-08
|
||||
- Fixed an issue where test-started events would not be fired correctly after a test performing a domain reload (case 1141530).
|
||||
- The UI should correctly run tests inside a nested class, when that class is selected.
|
||||
- All actions should now correctly display a prefix when reporting test result. E.g. "TearDown :".
|
||||
- Errors logged with Debug.LogError in TearDowns now append the error, rather than overwriting the existing result (case 1114306).
|
||||
- Incorrect implementations of IWrapTestMethod and IWrapSetUpTearDown now gives a meaningful error.
|
||||
- Fixed a regression where the Test Framework would run TearDown in a base class before the inheriting class (case 1142553).
|
||||
- Fixed a regression introduced in 1.0.9 where tests with the Explicit attribute could no longer be executed.
|
||||
|
||||
## [1.0.9] - 2019-03-27
|
||||
- Fixed an issue where a corrupt instance of the test runner window would block for a new being opened.
|
||||
- Added the required modules to the list of package requirements.
|
||||
- Fixed an issue where errors would happen if the test filter ui was clicked before the ui is done loading.
|
||||
- Fix selecting items with duplicate names in test hierarchy of Test Runner window (case 987587).
|
||||
- Fixed RecompileScripts instruction which we use in tests (case 1128994).
|
||||
- Fixed an issue where using multiple filters on tests would sometimes give an incorrect result.
|
||||
|
||||
## [1.0.7] - 2019-03-12
|
||||
### This is the first release of *Unity Package com.unity.test-framework*.
|
||||
|
||||
- Migrated the test-framework from the current extension in unity.
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d691174143fd3774ba63d7c493633b99
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,9 @@
|
|||
# Contributing
|
||||
|
||||
## If you are interested in contributing, here are some ground rules:
|
||||
* ... Define guidelines & rules for what contributors need to know to successfully make Pull requests against your repo ...
|
||||
|
||||
## All contributions are subject to the [Unity Contribution Agreement(UCA)](https://unity3d.com/legal/licenses/Unity_Contribution_Agreement)
|
||||
By making a pull request, you are confirming agreement to the terms and conditions of the UCA, including that your Contributions are your original creation and that you have complete right and authority to make your Contributions.
|
||||
|
||||
## Once you have a change ready following these ground rules. Simply make a pull request
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 57d2ac5c7d5786e499d4794973fe0d4e
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,5 @@
|
|||
Test Framework copyright © 2020 Unity Technologies ApS
|
||||
|
||||
Licensed under the Unity Companion License for Unity-dependent projects--see [Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License).
|
||||
|
||||
Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions.
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3ec7596410385054a9e0bc90377fbe63
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 95cdf27b47eb82747ba9e51f41e72a35
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fa423365b1ce06a4dbdc6fb4a8597bfa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 891bb6b9f5094c36b59c3788e21c8213
|
||||
timeCreated: 1638532925
|
|
@ -0,0 +1,162 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using NUnit.Framework.Internal;
|
||||
using UnityEditor.TestTools.TestRunner.TestRun;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestRunner.NUnitExtensions;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api.Analytics
|
||||
{
|
||||
internal static class AnalyticsReporter
|
||||
{
|
||||
private const string VendorKey = "unity.test-framework";
|
||||
private const string RunFinishedEventName = "runFinished";
|
||||
private const string AnalyzeTestTreeName = "analyzeTestTree";
|
||||
|
||||
private static bool isSetUp;
|
||||
private static IDictionary<string, bool> methodsAnalyzed;
|
||||
private static IDictionary<string, bool> typesAnalyzed;
|
||||
|
||||
private static void SetUpIfNeeded()
|
||||
{
|
||||
if (isSetUp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
isSetUp = true;
|
||||
EditorAnalytics.RegisterEventWithLimit(RunFinishedEventName, 60, 30, VendorKey);
|
||||
EditorAnalytics.RegisterEventWithLimit(AnalyzeTestTreeName, 3, 30, VendorKey);
|
||||
}
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
private static void RegisterCallbacks()
|
||||
{
|
||||
ScriptableObject.CreateInstance<TestRunnerApi>().RegisterCallbacks(new AnalyticsTestCallback(ReportRunFinished));
|
||||
}
|
||||
|
||||
private static void ReportRunFinished(ITestResultAdaptor testResult)
|
||||
{
|
||||
SetUpIfNeeded();
|
||||
|
||||
var activeRuns = TestJobDataHolder.instance.TestRuns;
|
||||
if (activeRuns.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var executionSettings = activeRuns[0].executionSettings;
|
||||
var filter = executionSettings.filters.First();
|
||||
var runFinishedData = new RunFinishedData()
|
||||
{
|
||||
totalTests = testResult.Test.TestCaseCount,
|
||||
numPassedTests = testResult.PassCount,
|
||||
numFailedTests = testResult.FailCount,
|
||||
numInconclusiveTests = testResult.InconclusiveCount,
|
||||
numSkippedTests = testResult.SkipCount,
|
||||
testModeFilter = (int)filter.testMode,
|
||||
targetPlatform = executionSettings.targetPlatform != null ? executionSettings.targetPlatform.ToString() : "editor",
|
||||
runSynchronously = executionSettings.runSynchronously,
|
||||
isCustomRunner = false,
|
||||
isFiltering = executionSettings.filters.Any(f => f.HasAny()),
|
||||
isAutomated = IsCommandLineArgSet("-automated"),
|
||||
isFromCommandLine = IsCommandLineArgSet("-runTests"),
|
||||
totalTestDuration = testResult.Duration,
|
||||
totalRunDuration = (DateTime.Now - Convert.ToDateTime(activeRuns[0].startTime)).TotalSeconds
|
||||
};
|
||||
|
||||
EditorAnalytics.SendEventWithLimit(RunFinishedEventName, runFinishedData, 1);
|
||||
}
|
||||
|
||||
private static bool IsCommandLineArgSet(string command)
|
||||
{
|
||||
return Environment.GetCommandLineArgs().Any(c => c == command);
|
||||
}
|
||||
|
||||
internal static void AnalyzeTestTreeAndReport(ITest testTree)
|
||||
{
|
||||
SetUpIfNeeded();
|
||||
|
||||
typesAnalyzed = new Dictionary<string, bool>();
|
||||
methodsAnalyzed = new Dictionary<string, bool>();
|
||||
var data = new TestTreeData();
|
||||
AnalyzeTestTreeNode(testTree, data);
|
||||
EditorAnalytics.SendEventWithLimit(AnalyzeTestTreeName, data, 1);
|
||||
}
|
||||
|
||||
private static void AnalyzeTestTreeNode(ITest node, TestTreeData data)
|
||||
{
|
||||
var attributes = GetAttributes(node).ToArray();
|
||||
if (attributes.OfType<TestAttribute>().Any())
|
||||
{
|
||||
data.numTestAttributes++;
|
||||
}
|
||||
if (attributes.OfType<UnityTestAttribute>().Any())
|
||||
{
|
||||
data.numUnityTestAttributes++;
|
||||
}
|
||||
if (attributes.OfType<CategoryAttribute>().Any())
|
||||
{
|
||||
data.numCategoryAttributes++;
|
||||
}
|
||||
if (attributes.OfType<TestFixtureAttribute>().Any())
|
||||
{
|
||||
data.numTestFixtureAttributes++;
|
||||
}
|
||||
if (attributes.OfType<ConditionalIgnoreAttribute>().Any())
|
||||
{
|
||||
data.numConditionalIgnoreAttributes++;
|
||||
}
|
||||
if (attributes.OfType<UnityPlatformAttribute>().Any())
|
||||
{
|
||||
data.numUnityPlatformAttributes++;
|
||||
}
|
||||
|
||||
if (node.HasChildren)
|
||||
{
|
||||
foreach (var test in node.Tests)
|
||||
{
|
||||
AnalyzeTestTreeNode(test, data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data.totalNumberOfTests++;
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<NUnitAttribute> GetAttributes(ITest node)
|
||||
{
|
||||
if (node.Method != null)
|
||||
{
|
||||
var key = $"{node.MethodName},{node.ClassName}";
|
||||
if (methodsAnalyzed.ContainsKey(key))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
methodsAnalyzed[key] = true;
|
||||
foreach (var attribute in (node).Method.GetCustomAttributes<NUnitAttribute>(true))
|
||||
{
|
||||
yield return attribute;
|
||||
}
|
||||
|
||||
var typeKey = node.Method.TypeInfo.FullName;
|
||||
if (typesAnalyzed.ContainsKey(typeKey))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
typesAnalyzed[typeKey] = true;
|
||||
foreach (var attribute in node.Method.TypeInfo.GetCustomAttributes<NUnitAttribute>(true))
|
||||
{
|
||||
yield return attribute;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a85430cc5a4a4279a992be322de12b29
|
||||
timeCreated: 1638532946
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api.Analytics
|
||||
{
|
||||
internal class AnalyticsTestCallback : ICallbacks
|
||||
{
|
||||
private Action<ITestResultAdaptor> _runFinishedCallback;
|
||||
|
||||
public AnalyticsTestCallback(Action<ITestResultAdaptor> runFinishedCallback)
|
||||
{
|
||||
_runFinishedCallback = runFinishedCallback;
|
||||
}
|
||||
|
||||
public void RunStarted(ITestAdaptor testsToRun)
|
||||
{
|
||||
}
|
||||
|
||||
public void RunFinished(ITestResultAdaptor result)
|
||||
{
|
||||
_runFinishedCallback(result);
|
||||
}
|
||||
|
||||
public void TestStarted(ITestAdaptor test)
|
||||
{
|
||||
}
|
||||
|
||||
public void TestFinished(ITestResultAdaptor result)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f5e82966bb8646269e2e46b6ddf2d89f
|
||||
timeCreated: 1638535350
|
|
@ -0,0 +1,20 @@
|
|||
namespace UnityEditor.TestTools.TestRunner.Api.Analytics
|
||||
{
|
||||
internal class RunFinishedData
|
||||
{
|
||||
public int totalTests;
|
||||
public int numPassedTests;
|
||||
public int numFailedTests;
|
||||
public int numInconclusiveTests;
|
||||
public int numSkippedTests;
|
||||
public int testModeFilter;
|
||||
public bool isAutomated;
|
||||
public bool isFromCommandLine;
|
||||
public bool isFiltering;
|
||||
public string targetPlatform;
|
||||
public double totalTestDuration;
|
||||
public double totalRunDuration;
|
||||
public bool runSynchronously;
|
||||
public bool isCustomRunner;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: dc781c79a6ac490f817bb70a01490d5c
|
||||
timeCreated: 1638533438
|
|
@ -0,0 +1,15 @@
|
|||
namespace UnityEditor.TestTools.TestRunner.Api.Analytics
|
||||
{
|
||||
internal class TestTreeData
|
||||
{
|
||||
public int totalNumberOfTests;
|
||||
public int numTestAttributes;
|
||||
public int numUnityTestAttributes;
|
||||
public int numCategoryAttributes;
|
||||
public int numTestFixtureAttributes;
|
||||
public int numConditionalIgnoreAttributes;
|
||||
public int numRequiresPlayModeAttributesTrue;
|
||||
public int numRequiresPlayModeAttributesFalse;
|
||||
public int numUnityPlatformAttributes;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 697ab794770540d6951f83d62b8fa444
|
||||
timeCreated: 1639043038
|
|
@ -0,0 +1,136 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using NUnit.Framework.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestRunner.TestLaunchers;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
internal class CallbacksDelegator : ICallbacksDelegator
|
||||
{
|
||||
private static CallbacksDelegator s_instance;
|
||||
public static CallbacksDelegator instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_instance == null)
|
||||
{
|
||||
s_instance = new CallbacksDelegator(CallbacksHolder.instance.GetAll, new TestAdaptorFactory());
|
||||
}
|
||||
return s_instance;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Func<ICallbacks[]> m_CallbacksProvider;
|
||||
private readonly ITestAdaptorFactory m_AdaptorFactory;
|
||||
|
||||
public CallbacksDelegator(Func<ICallbacks[]> callbacksProvider, ITestAdaptorFactory adaptorFactory)
|
||||
{
|
||||
m_CallbacksProvider = callbacksProvider;
|
||||
m_AdaptorFactory = adaptorFactory;
|
||||
}
|
||||
|
||||
public void RunStarted(ITest testsToRun)
|
||||
{
|
||||
m_AdaptorFactory.ClearResultsCache();
|
||||
var testRunnerTestsToRun = m_AdaptorFactory.Create(testsToRun);
|
||||
TryInvokeAllCallbacks(callbacks => callbacks.RunStarted(testRunnerTestsToRun));
|
||||
}
|
||||
|
||||
public void RunStartedRemotely(byte[] testsToRunData)
|
||||
{
|
||||
var testData = Deserialize<RemoteTestResultDataWithTestData>(testsToRunData);
|
||||
var testsToRun = m_AdaptorFactory.BuildTree(testData);
|
||||
TryInvokeAllCallbacks(callbacks => callbacks.RunStarted(testsToRun));
|
||||
}
|
||||
|
||||
public void RunFinished(ITestResult testResults)
|
||||
{
|
||||
var testResult = m_AdaptorFactory.Create(testResults);
|
||||
TryInvokeAllCallbacks(callbacks => callbacks.RunFinished(testResult));
|
||||
}
|
||||
|
||||
public void RunFinishedRemotely(byte[] testResultsData)
|
||||
{
|
||||
var remoteTestResult = Deserialize<RemoteTestResultDataWithTestData>(testResultsData);
|
||||
var testResult = m_AdaptorFactory.Create(remoteTestResult.results.First(), remoteTestResult);
|
||||
TryInvokeAllCallbacks(callbacks => callbacks.RunFinished(testResult));
|
||||
}
|
||||
|
||||
public void RunFailed(string failureMessage)
|
||||
{
|
||||
Debug.LogError(failureMessage);
|
||||
TryInvokeAllCallbacks(callbacks =>
|
||||
{
|
||||
var errorCallback = callbacks as IErrorCallbacks;
|
||||
if (errorCallback != null)
|
||||
{
|
||||
errorCallback.OnError(failureMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void TestStarted(ITest test)
|
||||
{
|
||||
var testRunnerTest = m_AdaptorFactory.Create(test);
|
||||
TryInvokeAllCallbacks(callbacks => callbacks.TestStarted(testRunnerTest));
|
||||
}
|
||||
|
||||
public void TestStartedRemotely(byte[] testStartedData)
|
||||
{
|
||||
var testData = Deserialize<RemoteTestResultDataWithTestData>(testStartedData);
|
||||
var testsToRun = m_AdaptorFactory.BuildTree(testData);
|
||||
|
||||
TryInvokeAllCallbacks(callbacks => callbacks.TestStarted(testsToRun));
|
||||
}
|
||||
|
||||
public void TestFinished(ITestResult result)
|
||||
{
|
||||
var testResult = m_AdaptorFactory.Create(result);
|
||||
TryInvokeAllCallbacks(callbacks => callbacks.TestFinished(testResult));
|
||||
}
|
||||
|
||||
public void TestFinishedRemotely(byte[] testResultsData)
|
||||
{
|
||||
var remoteTestResult = Deserialize<RemoteTestResultDataWithTestData>(testResultsData);
|
||||
var testResult = m_AdaptorFactory.Create(remoteTestResult.results.First(), remoteTestResult);
|
||||
TryInvokeAllCallbacks(callbacks => callbacks.TestFinished(testResult));
|
||||
}
|
||||
|
||||
public void TestTreeRebuild(ITest test)
|
||||
{
|
||||
m_AdaptorFactory.ClearTestsCache();
|
||||
var testAdaptor = m_AdaptorFactory.Create(test);
|
||||
TryInvokeAllCallbacks(callbacks =>
|
||||
{
|
||||
var rebuildCallbacks = callbacks as ITestTreeRebuildCallbacks;
|
||||
if (rebuildCallbacks != null)
|
||||
{
|
||||
rebuildCallbacks.TestTreeRebuild(testAdaptor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void TryInvokeAllCallbacks(Action<ICallbacks> callbackAction)
|
||||
{
|
||||
foreach (var testRunnerApiCallback in m_CallbacksProvider())
|
||||
{
|
||||
try
|
||||
{
|
||||
callbackAction(testRunnerApiCallback);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static T Deserialize<T>(byte[] data)
|
||||
{
|
||||
return JsonUtility.FromJson<T>(Encoding.UTF8.GetString(data));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0de03ebd74e2b474fa23d05ab42d0cd8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,28 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.TestTools.TestRunner;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
internal class CallbacksDelegatorListener : ScriptableObject, ITestRunnerListener
|
||||
{
|
||||
public void RunStarted(NUnit.Framework.Interfaces.ITest testsToRun)
|
||||
{
|
||||
CallbacksDelegator.instance.RunStarted(testsToRun);
|
||||
}
|
||||
|
||||
public void RunFinished(NUnit.Framework.Interfaces.ITestResult testResults)
|
||||
{
|
||||
CallbacksDelegator.instance.RunFinished(testResults);
|
||||
}
|
||||
|
||||
public void TestStarted(NUnit.Framework.Interfaces.ITest test)
|
||||
{
|
||||
CallbacksDelegator.instance.TestStarted(test);
|
||||
}
|
||||
|
||||
public void TestFinished(NUnit.Framework.Interfaces.ITestResult result)
|
||||
{
|
||||
CallbacksDelegator.instance.TestFinished(result);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f3e1b3cbf3fac6a459b1a602167ad311
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
internal class CallbacksHolder : ScriptableSingleton<CallbacksHolder>, ICallbacksHolder
|
||||
{
|
||||
private List<CallbackWithPriority> m_Callbacks = new List<CallbackWithPriority>();
|
||||
public void Add(ICallbacks callback, int priority)
|
||||
{
|
||||
m_Callbacks.Add(new CallbackWithPriority(callback, priority));
|
||||
}
|
||||
|
||||
public void Remove(ICallbacks callback)
|
||||
{
|
||||
m_Callbacks.RemoveAll(callbackWithPriority => callbackWithPriority.Callback == callback);
|
||||
}
|
||||
|
||||
public ICallbacks[] GetAll()
|
||||
{
|
||||
return m_Callbacks.OrderByDescending(callback => callback.Priority).Select(callback => callback.Callback).ToArray();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
m_Callbacks.Clear();
|
||||
}
|
||||
|
||||
private struct CallbackWithPriority
|
||||
{
|
||||
public ICallbacks Callback;
|
||||
public int Priority;
|
||||
public CallbackWithPriority(ICallbacks callback, int priority)
|
||||
{
|
||||
Callback = callback;
|
||||
Priority = priority;
|
||||
}
|
||||
}
|
||||
|
||||
// Sometimes - such as when we want to test the test framework itself - it's necessary to launch a test run from
|
||||
// inside a test. Because callbacks are registered globally, this can cause a lot of confusion (e.g. the in-test
|
||||
// run will emit UTP messages, utterly confusing UTR). In such circumstances the safest thing to do is to
|
||||
// temporarily suppress all registered callbacks for the duration of the in-test run. This method can be called
|
||||
// to set up a using() block which will suppress the callbacks for the scope.
|
||||
public IDisposable TemporarilySuppressCallbacks()
|
||||
{
|
||||
return new Suppressor(this);
|
||||
}
|
||||
|
||||
private sealed class Suppressor : IDisposable
|
||||
{
|
||||
private readonly CallbacksHolder _instance;
|
||||
private readonly List<CallbackWithPriority> _suppressed;
|
||||
|
||||
public Suppressor(CallbacksHolder instance)
|
||||
{
|
||||
_instance = instance;
|
||||
_suppressed = new List<CallbackWithPriority>(instance.m_Callbacks);
|
||||
instance.m_Callbacks.Clear();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_instance.m_Callbacks.AddRange(_suppressed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4884ccc3528cb2e40a0e6f0a19a2b35b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using NUnit.Framework.Internal.Filters;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// A set of execution settings defining how to run tests, using the <see cref="TestRunnerApi"/>.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ExecutionSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an instance with a given set of filters, if any.
|
||||
/// </summary>
|
||||
/// <param name="filtersToExecute">Set of filters</param>
|
||||
public ExecutionSettings(params Filter[] filtersToExecute)
|
||||
{
|
||||
filters = filtersToExecute;
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
internal BuildTarget? targetPlatform;
|
||||
|
||||
/// <summary>
|
||||
/// An instance of <see cref="ITestRunSettings"/> to set up before running tests on a Player.
|
||||
/// </summary>
|
||||
// Note: Is not available after serialization
|
||||
public ITestRunSettings overloadTestRunSettings;
|
||||
|
||||
[SerializeField]
|
||||
internal Filter filter;
|
||||
///<summary>
|
||||
///A collection of <see cref="Filter"/> to execute tests on.
|
||||
///</summary>
|
||||
[SerializeField]
|
||||
public Filter[] filters;
|
||||
/// <summary>
|
||||
/// Note that this is only supported for EditMode tests, and that tests which take multiple frames (i.e. [UnityTest] tests, or tests with [UnitySetUp] or [UnityTearDown] scaffolding) will be filtered out.
|
||||
/// </summary>
|
||||
/// <returns>If true, the call to Execute() will run tests synchronously, guaranteeing that all tests have finished running by the time the call returns.</returns>
|
||||
[SerializeField]
|
||||
public bool runSynchronously;
|
||||
/// <summary>
|
||||
/// The time, in seconds, the editor should wait for heartbeats after starting a test run on a player. This defaults to 10 minutes.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public int playerHeartbeatTimeout = 60*10;
|
||||
internal string playerSavePath { get; set; }
|
||||
|
||||
internal bool EditModeIncluded()
|
||||
{
|
||||
return filters.Any(f => IncludesTestMode(f.testMode, TestMode.EditMode));
|
||||
}
|
||||
|
||||
internal bool PlayModeInEditorIncluded()
|
||||
{
|
||||
return filters.Any(f => IncludesTestMode(f.testMode, TestMode.PlayMode) && targetPlatform == null);
|
||||
}
|
||||
|
||||
internal bool PlayerIncluded()
|
||||
{
|
||||
return filters.Any(f => IncludesTestMode(f.testMode, TestMode.PlayMode) && targetPlatform != null);
|
||||
}
|
||||
|
||||
private static bool IncludesTestMode(TestMode testMode, TestMode modeToCheckFor)
|
||||
{
|
||||
return (testMode & modeToCheckFor) == modeToCheckFor;
|
||||
}
|
||||
|
||||
internal ITestFilter BuildNUnitFilter()
|
||||
{
|
||||
return new OrFilter(filters.Select(f => f.ToRuntimeTestRunnerFilter(runSynchronously).BuildNUnitFilter()).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: eea34a28297f9bc4c9f4c573bc8d5d1c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools.TestRunner.GUI;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// The filter class provides the <see cref="TestRunnerApi"/> with a specification of what tests to run when [running tests programmatically](https://docs.unity3d.com/Packages/com.unity.test-framework@1.1/manual/extension-run-tests.html).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Filter
|
||||
{
|
||||
/// <summary>
|
||||
/// An enum flag that specifies if Edit Mode or Play Mode tests should run.
|
||||
///</summary>
|
||||
[SerializeField]
|
||||
public TestMode testMode;
|
||||
/// <summary>
|
||||
/// The full name of the tests to match the filter. This is usually in the format FixtureName.TestName. If the test has test arguments, then include them in parenthesis. E.g. MyTestClass2.MyTestWithMultipleValues(1).
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public string[] testNames;
|
||||
/// <summary>
|
||||
/// The same as testNames, except that it allows for Regex. This is useful for running specific fixtures or namespaces. E.g. "^MyNamespace\\." Runs any tests where the top namespace is MyNamespace.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public string[] groupNames;
|
||||
/// <summary>
|
||||
/// The name of a [Category](https://nunit.org/docs/2.2.7/category.html) to include in the run. Any test or fixtures runs that have a Category matching the string.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public string[] categoryNames;
|
||||
/// <summary>
|
||||
/// The name of assemblies included in the run. That is the assembly name, without the .dll file extension. E.g., MyTestAssembly
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public string[] assemblyNames;
|
||||
/// <summary>
|
||||
/// The <see cref="BuildTarget"/> platform to run the test on. If set to null, then the Editor is the target for the tests.
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
public BuildTarget? targetPlatform;
|
||||
|
||||
internal RuntimeTestRunnerFilter ToRuntimeTestRunnerFilter(bool synchronousOnly)
|
||||
{
|
||||
return new RuntimeTestRunnerFilter()
|
||||
{
|
||||
testNames = testNames,
|
||||
categoryNames = categoryNames,
|
||||
groupNames = groupNames,
|
||||
assemblyNames = assemblyNames,
|
||||
synchronousOnly = synchronousOnly
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
internal bool HasAny()
|
||||
{
|
||||
return assemblyNames != null && assemblyNames.Any()
|
||||
|| categoryNames != null && categoryNames.Any()
|
||||
|| groupNames != null && groupNames.Any()
|
||||
|| testNames != null && testNames.Any();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 05f92e4a2414cb144a92157752dfa324
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,29 @@
|
|||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// Callbacks in the <see cref="TestRunnerApi"/> for the test stages when running tests.
|
||||
/// </summary>
|
||||
public interface ICallbacks
|
||||
{
|
||||
/// <summary>
|
||||
/// A callback invoked when a test run is started.
|
||||
/// </summary>
|
||||
/// <param name="testsToRun">The full loaded test tree.</param>
|
||||
void RunStarted(ITestAdaptor testsToRun);
|
||||
/// <summary>
|
||||
/// A callback invoked when a test run is finished.
|
||||
/// </summary>
|
||||
/// <param name="result">The result of the test run.</param>
|
||||
void RunFinished(ITestResultAdaptor result);
|
||||
/// <summary>
|
||||
/// A callback invoked when each individual node of the test tree has started executing.
|
||||
/// </summary>
|
||||
/// <param name="test">The test node currently executed.</param>
|
||||
void TestStarted(ITestAdaptor test);
|
||||
/// <summary>
|
||||
/// A callback invoked when each individual node of the test tree has finished executing.
|
||||
/// </summary>
|
||||
/// <param name="result">The result of the test tree node after it had been executed.</param>
|
||||
void TestFinished(ITestResultAdaptor result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 93eea84e53d0226479c9a584f19427b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,18 @@
|
|||
using NUnit.Framework.Interfaces;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
internal interface ICallbacksDelegator
|
||||
{
|
||||
void RunStarted(ITest testsToRun);
|
||||
void RunStartedRemotely(byte[] testsToRunData);
|
||||
void RunFinished(ITestResult testResults);
|
||||
void RunFinishedRemotely(byte[] testResultsData);
|
||||
void RunFailed(string failureMessage);
|
||||
void TestStarted(ITest test);
|
||||
void TestStartedRemotely(byte[] testStartedData);
|
||||
void TestFinished(ITestResult result);
|
||||
void TestFinishedRemotely(byte[] testResultsData);
|
||||
void TestTreeRebuild(ITest test);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8f8f74fe8e363da42875d9cab025d3b2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,10 @@
|
|||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
internal interface ICallbacksHolder
|
||||
{
|
||||
void Add(ICallbacks callback, int priority);
|
||||
void Remove(ICallbacks callback);
|
||||
ICallbacks[] GetAll();
|
||||
void Clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d742f2caefd9f934d9f19dad07a08e6f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
|||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// An extended version of the <see cref="ICallbacks"/>, which get invoked if the test run fails due to a build error or if any <see cref="UnityEngine.TestTools.IPrebuildSetup"/> has a failure.
|
||||
/// </summary>
|
||||
public interface IErrorCallbacks : ICallbacks
|
||||
{
|
||||
/// <summary>
|
||||
/// Method invoked on failure.
|
||||
/// </summary>
|
||||
/// <param name="message">
|
||||
/// The error message detailing the reason for the run to fail.
|
||||
/// </param>
|
||||
void OnError(string message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1a06c562b0c5eb046bcb876a29f93c98
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,100 @@
|
|||
using System.Collections.Generic;
|
||||
using NUnit.Framework.Interfaces;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// ```ITestAdaptor``` is a representation of a node in the test tree implemented as a wrapper around the [NUnit](http://www.nunit.org/) [ITest](https://github.com/nunit/nunit/blob/master/src/NUnitFramework/framework/Interfaces/ITest.cs) interface.
|
||||
/// </summary>
|
||||
public interface ITestAdaptor
|
||||
{
|
||||
/// <summary>
|
||||
/// The ID of the test tree node. The ID can change if you add new tests to the suite. Use UniqueName, if you want to have a more permanent point of reference.
|
||||
/// </summary>
|
||||
string Id { get; }
|
||||
/// <summary>
|
||||
/// The name of the test. E.g.,```MyTest```.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
/// <summary>
|
||||
/// The full name of the test. E.g., ```MyNamespace.MyTestClass.MyTest```.
|
||||
/// </summary>
|
||||
string FullName { get; }
|
||||
/// <summary>
|
||||
/// The total number of test cases in the node and all sub-nodes.
|
||||
/// </summary>
|
||||
int TestCaseCount { get; }
|
||||
/// <summary>
|
||||
/// Whether the node has any children.
|
||||
/// </summary>
|
||||
bool HasChildren { get; }
|
||||
/// <summary>
|
||||
/// True if the node is a test suite/fixture, false otherwise.
|
||||
/// </summary>
|
||||
bool IsSuite { get; }
|
||||
/// <summary>
|
||||
/// The child nodes.
|
||||
/// </summary>
|
||||
IEnumerable<ITestAdaptor> Children { get; }
|
||||
/// <summary>
|
||||
/// The parent node, if any.
|
||||
/// </summary>
|
||||
ITestAdaptor Parent { get; }
|
||||
/// <summary>
|
||||
/// The test case timeout in milliseconds. Note that this value is only available on TestFinished.
|
||||
/// </summary>
|
||||
int TestCaseTimeout { get; }
|
||||
/// <summary>
|
||||
/// The type of test class as an ```NUnit``` <see cref="ITypeInfo"/>. If the node is not a test class, then the value is null.
|
||||
/// </summary>
|
||||
ITypeInfo TypeInfo { get; }
|
||||
/// <summary>
|
||||
/// The Nunit <see cref="IMethodInfo"/> of the test method. If the node is not a test method, then the value is null.
|
||||
/// </summary>
|
||||
IMethodInfo Method { get; }
|
||||
/// <summary>
|
||||
/// An array of the categories applied to the test or fixture.
|
||||
/// </summary>
|
||||
string[] Categories { get; }
|
||||
/// <summary>
|
||||
/// Returns true if the node represents a test assembly, false otherwise.
|
||||
/// </summary>
|
||||
bool IsTestAssembly { get; }
|
||||
/// <summary>
|
||||
/// The run state of the test node. Either ```NotRunnable```, ```Runnable```, ```Explicit```, ```Skipped```, or ```Ignored```.
|
||||
/// </summary>
|
||||
RunState RunState { get; }
|
||||
/// <summary>
|
||||
/// The description of the test.
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
/// <summary>
|
||||
/// The skip reason. E.g., if ignoring the test.
|
||||
/// </summary>
|
||||
string SkipReason { get; }
|
||||
/// <summary>
|
||||
/// The ID of the parent node.
|
||||
/// </summary>
|
||||
string ParentId { get; }
|
||||
/// <summary>
|
||||
/// The full name of the parent node.
|
||||
/// </summary>
|
||||
string ParentFullName { get; }
|
||||
/// <summary>
|
||||
/// A unique generated name for the test node. E.g., ```Tests.dll/MyNamespace/MyTestClass/[Tests][MyNamespace.MyTestClass.MyTest]```.
|
||||
/// </summary>
|
||||
string UniqueName { get; }
|
||||
/// <summary>
|
||||
/// A unique name of the parent node. E.g., ```Tests.dll/MyNamespace/[Tests][MyNamespace.MyTestClass][suite]```.
|
||||
/// </summary>
|
||||
string ParentUniqueName { get; }
|
||||
/// <summary>
|
||||
/// The child index of the node in its parent.
|
||||
/// </summary>
|
||||
int ChildIndex { get; }
|
||||
/// <summary>
|
||||
/// The mode of the test. Either **Edit Mode** or **Play Mode**.
|
||||
/// </summary>
|
||||
TestMode TestMode { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 85dd7af03f02aea4aae13a3945e3b313
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,18 @@
|
|||
using System.Collections.Generic;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEngine.TestRunner.TestLaunchers;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
internal interface ITestAdaptorFactory
|
||||
{
|
||||
ITestAdaptor Create(ITest test);
|
||||
ITestAdaptor Create(RemoteTestData testData);
|
||||
ITestResultAdaptor Create(ITestResult testResult);
|
||||
ITestResultAdaptor Create(RemoteTestResultData testResult, RemoteTestResultDataWithTestData allData);
|
||||
ITestAdaptor BuildTree(RemoteTestResultDataWithTestData data);
|
||||
IEnumerator<ITestAdaptor> BuildTreeAsync(RemoteTestResultDataWithTestData data);
|
||||
void ClearResultsCache();
|
||||
void ClearTestsCache();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 803abab0f7e17044db56f8760186dbd1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,121 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework.Interfaces;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// The `ITestResultAdaptor` is the representation of the test results for a node in the test tree implemented as a wrapper around the [NUnit](http://www.nunit.org/) [ITest](https://github.com/nunit/nunit/blob/master/src/NUnitFramework/framework/Interfaces/ITestResults.cs) interface.
|
||||
/// </summary>
|
||||
public interface ITestResultAdaptor
|
||||
{
|
||||
/// <summary>
|
||||
/// The test details of the test result tree node as a <see cref="TestAdaptor"/>
|
||||
/// </summary>
|
||||
ITestAdaptor Test { get; }
|
||||
///<summary>
|
||||
///The name of the test node.
|
||||
///</summary>
|
||||
string Name { get; }
|
||||
/// <summary>
|
||||
/// Gets the full name of the test result
|
||||
/// </summary>
|
||||
///<returns>
|
||||
///The name of the test result.
|
||||
///</returns>
|
||||
string FullName { get; }
|
||||
///<summary>
|
||||
///Gets the state of the result as a string.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///It returns one of these values: `Inconclusive`, `Skipped`, `Skipped:Ignored`, `Skipped:Explicit`, `Passed`, `Failed`, `Failed:Error`, `Failed:Cancelled`, `Failed:Invalid`
|
||||
///</returns>
|
||||
string ResultState { get; }
|
||||
///<summary>
|
||||
///Gets the status of the test as an enum.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///It returns one of these values:`Inconclusive`, `Skipped`, `Passed`, or `Failed`
|
||||
///</returns>
|
||||
TestStatus TestStatus { get; }
|
||||
/// <summary>
|
||||
/// Gets the elapsed time for running the test in seconds
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Time in seconds.
|
||||
/// </returns>
|
||||
double Duration { get; }
|
||||
/// <summary>
|
||||
/// Gets or sets the time the test started running.
|
||||
/// </summary>
|
||||
///<returns>
|
||||
///A DataTime object.
|
||||
///</returns>
|
||||
DateTime StartTime { get; }
|
||||
///<summary>
|
||||
///Gets or sets the time the test finished running.
|
||||
///</summary>
|
||||
///<returns>
|
||||
///A DataTime object.
|
||||
///</returns>
|
||||
DateTime EndTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The message associated with a test failure or with not running the test
|
||||
/// </summary>
|
||||
string Message { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Any stacktrace associated with an error or failure. Not available in the Compact Framework 1.0.
|
||||
/// </summary>
|
||||
string StackTrace { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of asserts executed when running the test and all its children.
|
||||
/// </summary>
|
||||
int AssertCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of test cases that failed when running the test and all its children.
|
||||
/// </summary>
|
||||
int FailCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of test cases that passed when running the test and all its children.
|
||||
/// </summary>
|
||||
int PassCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of test cases that were skipped when running the test and all its children.
|
||||
/// </summary>
|
||||
int SkipCount { get; }
|
||||
|
||||
/// <summary>
|
||||
///The number of test cases that were inconclusive when running the test and all its children.
|
||||
/// </summary>
|
||||
int InconclusiveCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Accessing HasChildren should not force creation of the Children collection in classes implementing this interface.
|
||||
/// </summary>
|
||||
/// <returns>True if this result has any child results.</returns>
|
||||
bool HasChildren { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the the collection of child results.
|
||||
/// </summary>
|
||||
IEnumerable<ITestResultAdaptor> Children { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets any text output written to this result.
|
||||
/// </summary>
|
||||
string Output { get; }
|
||||
/// <summary>
|
||||
/// Use this to save the results to an XML file
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The test results as an `NUnit` XML node.
|
||||
/// </returns>
|
||||
TNode ToXml();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4f90cfe4bf5cfb44f84a5b11387f2a42
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// ITestRunSettings lets you set any of the global settings right before building a Player for a test run and then reverts the settings afterward. ITestRunSettings implements
|
||||
/// [IDisposable](https://docs.microsoft.com/en-us/dotnet/api/system.idisposable?view=netframework-4.8), and runs after building the Player with tests.
|
||||
/// </summary>
|
||||
public interface ITestRunSettings : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// A method called before building the Player.
|
||||
/// </summary>
|
||||
void Apply();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2ae2ce6274819484fa8747a28cebdf3a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
internal interface ITestRunnerApi
|
||||
{
|
||||
string Execute(ExecutionSettings executionSettings);
|
||||
void RegisterCallbacks<T>(T testCallbacks, int priority = 0) where T : ICallbacks;
|
||||
void UnregisterCallbacks<T>(T testCallbacks) where T : ICallbacks;
|
||||
void RetrieveTestList(TestMode testMode, Action<ITestAdaptor> callback);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a7842a837a4b13e41ae16193db753418
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,7 @@
|
|||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
internal interface ITestTreeRebuildCallbacks : ICallbacks
|
||||
{
|
||||
void TestTreeRebuild(ITestAdaptor test);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4230e406313f1db43a4b548e7a3ad2e2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,33 @@
|
|||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// The RunState enum indicates whether a test can be executed.
|
||||
/// </summary>
|
||||
public enum RunState
|
||||
{
|
||||
/// <summary>
|
||||
/// The test is not runnable.
|
||||
/// </summary>
|
||||
NotRunnable,
|
||||
|
||||
/// <summary>
|
||||
/// The test is runnable.
|
||||
/// </summary>
|
||||
Runnable,
|
||||
|
||||
/// <summary>
|
||||
/// The test can only be run explicitly
|
||||
/// </summary>
|
||||
Explicit,
|
||||
|
||||
/// <summary>
|
||||
/// The test has been skipped. This value may appear on a Test when certain attributes are used to skip the test.
|
||||
/// </summary>
|
||||
Skipped,
|
||||
|
||||
/// <summary>
|
||||
/// The test has been ignored. May appear on a Test, when the IgnoreAttribute is used.
|
||||
/// </summary>
|
||||
Ignored,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8bb59cb2f66d156418ca1bd1e2703233
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,142 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using NUnit.Framework.Internal;
|
||||
using UnityEngine.TestRunner.NUnitExtensions;
|
||||
using UnityEngine.TestRunner.NUnitExtensions.Runner;
|
||||
using UnityEngine.TestRunner.TestLaunchers;
|
||||
using UnityEngine.TestTools.Utils;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
internal class TestAdaptor : ITestAdaptor
|
||||
{
|
||||
internal TestAdaptor(ITest test, ITestAdaptor[] children = null)
|
||||
{
|
||||
Id = test.Id;
|
||||
Name = test.Name;
|
||||
var childIndex = -1;
|
||||
if (test.Properties["childIndex"].Count > 0)
|
||||
{
|
||||
childIndex = (int)test.Properties["childIndex"][0];
|
||||
}
|
||||
FullName = childIndex != -1 ? GetIndexedTestCaseName(test.FullName, childIndex) : test.FullName;
|
||||
TestCaseCount = test.TestCaseCount;
|
||||
HasChildren = test.HasChildren;
|
||||
IsSuite = test.IsSuite;
|
||||
if (UnityTestExecutionContext.CurrentContext != null)
|
||||
{
|
||||
TestCaseTimeout = UnityTestExecutionContext.CurrentContext.TestCaseTimeout;
|
||||
}
|
||||
else
|
||||
{
|
||||
TestCaseTimeout = CoroutineRunner.k_DefaultTimeout;
|
||||
}
|
||||
|
||||
TypeInfo = test.TypeInfo;
|
||||
Method = test.Method;
|
||||
Categories = test.GetAllCategoriesFromTest().Distinct().ToArray();
|
||||
IsTestAssembly = test is TestAssembly;
|
||||
RunState = (RunState)Enum.Parse(typeof(RunState), test.RunState.ToString());
|
||||
Description = (string)test.Properties.Get(PropertyNames.Description);
|
||||
SkipReason = test.GetSkipReason();
|
||||
ParentId = test.GetParentId();
|
||||
ParentFullName = test.GetParentFullName();
|
||||
UniqueName = test.GetUniqueName();
|
||||
ParentUniqueName = test.GetParentUniqueName();
|
||||
ChildIndex = childIndex;
|
||||
|
||||
if (test.Parent != null)
|
||||
{
|
||||
if (test.Parent.Parent == null) // Assembly level
|
||||
{
|
||||
TestMode = (TestMode)Enum.Parse(typeof(TestMode),test.Properties.Get("platform").ToString());
|
||||
}
|
||||
}
|
||||
|
||||
Children = children;
|
||||
}
|
||||
|
||||
public void SetParent(ITestAdaptor parent)
|
||||
{
|
||||
Parent = parent;
|
||||
if (parent != null)
|
||||
{
|
||||
TestMode = parent.TestMode;
|
||||
}
|
||||
}
|
||||
|
||||
internal TestAdaptor(RemoteTestData test)
|
||||
{
|
||||
Id = test.id;
|
||||
Name = test.name;
|
||||
FullName = test.ChildIndex != -1 ? GetIndexedTestCaseName(test.fullName, test.ChildIndex) : test.fullName;
|
||||
TestCaseCount = test.testCaseCount;
|
||||
HasChildren = test.hasChildren;
|
||||
IsSuite = test.isSuite;
|
||||
m_ChildrenIds = test.childrenIds;
|
||||
TestCaseTimeout = test.testCaseTimeout;
|
||||
Categories = test.Categories;
|
||||
IsTestAssembly = test.IsTestAssembly;
|
||||
RunState = (RunState)Enum.Parse(typeof(RunState), test.RunState.ToString());
|
||||
Description = test.Description;
|
||||
SkipReason = test.SkipReason;
|
||||
ParentId = test.ParentId;
|
||||
UniqueName = test.UniqueName;
|
||||
ParentUniqueName = test.ParentUniqueName;
|
||||
ParentFullName = test.ParentFullName;
|
||||
ChildIndex = test.ChildIndex;
|
||||
TestMode = TestMode.PlayMode;
|
||||
}
|
||||
|
||||
internal void ApplyChildren(IEnumerable<TestAdaptor> allTests)
|
||||
{
|
||||
Children = m_ChildrenIds.Select(id => allTests.First(t => t.Id == id)).ToArray();
|
||||
if (!string.IsNullOrEmpty(ParentId))
|
||||
{
|
||||
Parent = allTests.FirstOrDefault(t => t.Id == ParentId);
|
||||
}
|
||||
}
|
||||
|
||||
public string Id { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
public string FullName { get; private set; }
|
||||
public int TestCaseCount { get; private set; }
|
||||
public bool HasChildren { get; private set; }
|
||||
public bool IsSuite { get; private set; }
|
||||
public IEnumerable<ITestAdaptor> Children { get; private set; }
|
||||
public ITestAdaptor Parent { get; private set; }
|
||||
public int TestCaseTimeout { get; private set; }
|
||||
public ITypeInfo TypeInfo { get; private set; }
|
||||
public IMethodInfo Method { get; private set; }
|
||||
private string[] m_ChildrenIds;
|
||||
public string[] Categories { get; private set; }
|
||||
public bool IsTestAssembly { get; private set; }
|
||||
public RunState RunState { get; }
|
||||
public string Description { get; }
|
||||
public string SkipReason { get; }
|
||||
public string ParentId { get; }
|
||||
public string ParentFullName { get; }
|
||||
public string UniqueName { get; }
|
||||
public string ParentUniqueName { get; }
|
||||
public int ChildIndex { get; }
|
||||
public TestMode TestMode { get; private set; }
|
||||
|
||||
private static string GetIndexedTestCaseName(string fullName, int index)
|
||||
{
|
||||
var generatedTestSuffix = " GeneratedTestCase" + index;
|
||||
if (fullName.EndsWith(")"))
|
||||
{
|
||||
// Test names from generated TestCaseSource look like Test(TestCaseSourceType)
|
||||
// This inserts a unique test case index in the name, so that it becomes Test(TestCaseSourceType GeneratedTestCase0)
|
||||
return fullName.Substring(0, fullName.Length - 1) + generatedTestSuffix + fullName[fullName.Length - 1];
|
||||
}
|
||||
|
||||
// In some cases there can be tests with duplicate names generated in other ways and they won't have () in their name
|
||||
// We just append a suffix at the end of the name in that case
|
||||
return fullName + generatedTestSuffix;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6e0e62db88935c74288c97c907243bd0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,91 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEngine.TestRunner.NUnitExtensions;
|
||||
using UnityEngine.TestRunner.TestLaunchers;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
internal class TestAdaptorFactory : ITestAdaptorFactory
|
||||
{
|
||||
private Dictionary<string, TestAdaptor> m_TestAdaptorCache = new Dictionary<string, TestAdaptor>();
|
||||
private Dictionary<string, TestResultAdaptor> m_TestResultAdaptorCache = new Dictionary<string, TestResultAdaptor>();
|
||||
public ITestAdaptor Create(ITest test)
|
||||
{
|
||||
var uniqueName = test.GetUniqueName();
|
||||
if (m_TestAdaptorCache.ContainsKey(uniqueName))
|
||||
{
|
||||
return m_TestAdaptorCache[uniqueName];
|
||||
}
|
||||
|
||||
var adaptor = new TestAdaptor(test, test.Tests.Select(Create).ToArray());
|
||||
foreach (var child in adaptor.Children)
|
||||
{
|
||||
(child as TestAdaptor).SetParent(adaptor);
|
||||
}
|
||||
m_TestAdaptorCache[uniqueName] = adaptor;
|
||||
return adaptor;
|
||||
}
|
||||
|
||||
public ITestAdaptor Create(RemoteTestData testData)
|
||||
{
|
||||
return new TestAdaptor(testData);
|
||||
}
|
||||
|
||||
public ITestResultAdaptor Create(ITestResult testResult)
|
||||
{
|
||||
var uniqueName = testResult.Test.GetUniqueName();
|
||||
if (m_TestResultAdaptorCache.ContainsKey(uniqueName))
|
||||
{
|
||||
return m_TestResultAdaptorCache[uniqueName];
|
||||
}
|
||||
var adaptor = new TestResultAdaptor(testResult, Create(testResult.Test), testResult.Children.Select(Create).ToArray());
|
||||
m_TestResultAdaptorCache[uniqueName] = adaptor;
|
||||
return adaptor;
|
||||
}
|
||||
|
||||
public ITestResultAdaptor Create(RemoteTestResultData testResult, RemoteTestResultDataWithTestData allData)
|
||||
{
|
||||
return new TestResultAdaptor(testResult, allData);
|
||||
}
|
||||
|
||||
public ITestAdaptor BuildTree(RemoteTestResultDataWithTestData data)
|
||||
{
|
||||
var tests = data.tests.Select(remoteTestData => new TestAdaptor(remoteTestData)).ToList();
|
||||
|
||||
foreach (var test in tests)
|
||||
{
|
||||
test.ApplyChildren(tests);
|
||||
}
|
||||
|
||||
return tests.First();
|
||||
}
|
||||
|
||||
public IEnumerator<ITestAdaptor> BuildTreeAsync(RemoteTestResultDataWithTestData data)
|
||||
{
|
||||
var tests = data.tests.Select(remoteTestData => new TestAdaptor(remoteTestData)).ToList();
|
||||
|
||||
for (var index = 0; index < tests.Count; index++)
|
||||
{
|
||||
var test = tests[index];
|
||||
test.ApplyChildren(tests);
|
||||
if (index % 100 == 0)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
yield return tests.First();
|
||||
}
|
||||
|
||||
public void ClearResultsCache()
|
||||
{
|
||||
m_TestResultAdaptorCache.Clear();
|
||||
}
|
||||
|
||||
public void ClearTestsCache()
|
||||
{
|
||||
m_TestAdaptorCache.Clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d0663d520c26b7c48a4135599e66acf8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// A flag indicating whether to run Edit Mode or Play Mode tests.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum TestMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Run EditMode tests.
|
||||
/// </summary>
|
||||
EditMode = 1 << 0,
|
||||
/// <summary>
|
||||
/// Run PlayMode tests.
|
||||
/// </summary>
|
||||
PlayMode = 1 << 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cad095eccea17b741bc4cd264e7441cd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,95 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEngine.TestRunner.TestLaunchers;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
internal class TestResultAdaptor : ITestResultAdaptor
|
||||
{
|
||||
private TNode m_Node;
|
||||
private ITestResult m_Result;
|
||||
|
||||
internal TestResultAdaptor(ITestResult result, ITestAdaptor test, ITestResultAdaptor[] children = null)
|
||||
{
|
||||
Test = test;
|
||||
Name = result.Name;
|
||||
FullName = result.FullName;
|
||||
ResultState = result.ResultState.ToString();
|
||||
TestStatus = ParseTestStatus(result.ResultState.Status);
|
||||
Duration = result.Duration;
|
||||
StartTime = result.StartTime;
|
||||
EndTime = result.EndTime;
|
||||
Message = result.Message;
|
||||
StackTrace = result.StackTrace;
|
||||
AssertCount = result.AssertCount;
|
||||
FailCount = result.FailCount;
|
||||
PassCount = result.PassCount;
|
||||
SkipCount = result.SkipCount;
|
||||
InconclusiveCount = result.InconclusiveCount;
|
||||
HasChildren = result.HasChildren;
|
||||
Output = result.Output;
|
||||
Children = children;
|
||||
m_Result = result;
|
||||
}
|
||||
|
||||
internal TestResultAdaptor(RemoteTestResultData result, RemoteTestResultDataWithTestData allData)
|
||||
{
|
||||
Test = new TestAdaptor(allData.tests.First(t => t.id == result.testId));
|
||||
Name = result.name;
|
||||
FullName = result.fullName;
|
||||
ResultState = result.resultState;
|
||||
TestStatus = ParseTestStatus(result.testStatus);
|
||||
Duration = result.duration;
|
||||
StartTime = result.startTime;
|
||||
EndTime = result.endTime;
|
||||
Message = result.message;
|
||||
StackTrace = result.stackTrace;
|
||||
AssertCount = result.assertCount;
|
||||
FailCount = result.failCount;
|
||||
PassCount = result.passCount;
|
||||
SkipCount = result.skipCount;
|
||||
InconclusiveCount = result.inconclusiveCount;
|
||||
HasChildren = result.hasChildren;
|
||||
Output = result.output;
|
||||
Children = result.childrenIds.Select(childId => new TestResultAdaptor(allData.results.First(r => r.testId == childId), allData)).ToArray();
|
||||
if (!string.IsNullOrEmpty(result.xml))
|
||||
{
|
||||
m_Node = TNode.FromXml(result.xml);
|
||||
}
|
||||
}
|
||||
|
||||
public ITestAdaptor Test { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
public string FullName { get; private set; }
|
||||
public string ResultState { get; private set; }
|
||||
public TestStatus TestStatus { get; private set; }
|
||||
public double Duration { get; private set; }
|
||||
public DateTime StartTime { get; private set; }
|
||||
public DateTime EndTime { get; private set; }
|
||||
public string Message { get; private set; }
|
||||
public string StackTrace { get; private set; }
|
||||
public int AssertCount { get; private set; }
|
||||
public int FailCount { get; private set; }
|
||||
public int PassCount { get; private set; }
|
||||
public int SkipCount { get; private set; }
|
||||
public int InconclusiveCount { get; private set; }
|
||||
public bool HasChildren { get; private set; }
|
||||
public IEnumerable<ITestResultAdaptor> Children { get; private set; }
|
||||
public string Output { get; private set; }
|
||||
public TNode ToXml()
|
||||
{
|
||||
if (m_Node == null)
|
||||
{
|
||||
m_Node = m_Result.ToXml(true);
|
||||
}
|
||||
return m_Node;
|
||||
}
|
||||
|
||||
private static TestStatus ParseTestStatus(NUnit.Framework.Interfaces.TestStatus testStatus)
|
||||
{
|
||||
return (TestStatus)Enum.Parse(typeof(TestStatus), testStatus.ToString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d061ada5d3169454daf54243390b5fdb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,158 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using UnityEditor.TestTools.TestRunner.CommandLineTest;
|
||||
using UnityEditor.TestTools.TestRunner.TestRun;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestRunner.TestLaunchers;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.TestTools.NUnitExtensions;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// The TestRunnerApi retrieves and runs tests programmatically from code inside the project, or inside other packages. TestRunnerApi is a [ScriptableObject](https://docs.unity3d.com/ScriptReference/ScriptableObject.html).
|
||||
///You can initialize the API like this:
|
||||
/// <code>
|
||||
/// var testRunnerApi = ScriptableObject.CreateInstance<TestRunnerApi>();
|
||||
/// </code>
|
||||
/// Note: You can subscribe and receive test results in one instance of the API, even if the run starts from another instance.
|
||||
/// The TestRunnerApi supports the following workflows:
|
||||
/// - [How to run tests programmatically](https://docs.unity3d.com/Packages/com.unity.test-framework@1.1/manual/extension-run-tests.html)
|
||||
/// - [How to get test results](https://docs.unity3d.com/Packages/com.unity.test-framework@1.1/manual/extension-get-test-results.html)
|
||||
/// - [How to retrieve the list of tests](https://docs.unity3d.com/Packages/com.unity.test-framework@1.1/manual/extension-retrieve-test-list.html)
|
||||
/// </summary>
|
||||
public class TestRunnerApi : ScriptableObject, ITestRunnerApi
|
||||
{
|
||||
internal ICallbacksHolder callbacksHolder;
|
||||
|
||||
private ICallbacksHolder m_CallbacksHolder
|
||||
{
|
||||
get
|
||||
{
|
||||
if (callbacksHolder == null)
|
||||
{
|
||||
return CallbacksHolder.instance;
|
||||
}
|
||||
|
||||
return callbacksHolder;
|
||||
}
|
||||
}
|
||||
|
||||
internal Func<ExecutionSettings,string> ScheduleJob = (executionSettings) =>
|
||||
{
|
||||
var runner = new TestJobRunner();
|
||||
return runner.RunJob(new TestJobData(executionSettings));
|
||||
};
|
||||
/// <summary>
|
||||
/// Starts a test run with a given set of executionSettings.
|
||||
/// </summary>
|
||||
/// <param name="executionSettings">Set of <see cref="ExecutionSettings"/></param>
|
||||
/// <returns>A GUID that identifies the TestJobData.</returns>
|
||||
public string Execute(ExecutionSettings executionSettings)
|
||||
{
|
||||
if (executionSettings == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(executionSettings));
|
||||
}
|
||||
|
||||
if ((executionSettings.filters == null || executionSettings.filters.Length == 0) && executionSettings.filter != null)
|
||||
{
|
||||
// Map filter (singular) to filters (plural), for backwards compatibility.
|
||||
executionSettings.filters = new [] {executionSettings.filter};
|
||||
}
|
||||
|
||||
if (executionSettings.targetPlatform == null && executionSettings.filters != null &&
|
||||
executionSettings.filters.Length > 0)
|
||||
{
|
||||
executionSettings.targetPlatform = executionSettings.filters[0].targetPlatform;
|
||||
}
|
||||
|
||||
return ScheduleJob(executionSettings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up a given instance of <see cref="ICallbacks"/> to be invoked on test runs.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// Generic representing a type of callback.
|
||||
/// </typeparam>
|
||||
/// <param name="testCallbacks">
|
||||
/// The test callbacks to be invoked.
|
||||
/// </param>
|
||||
/// <param name="priority">
|
||||
/// Sets the order in which the callbacks are invoked, starting with the highest value first.
|
||||
/// </param>
|
||||
public void RegisterCallbacks<T>(T testCallbacks, int priority = 0) where T : ICallbacks
|
||||
{
|
||||
if (testCallbacks == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(testCallbacks));
|
||||
}
|
||||
|
||||
m_CallbacksHolder.Add(testCallbacks, priority);
|
||||
}
|
||||
/// <summary>
|
||||
/// Unregister an instance of <see cref="ICallbacks"/> to no longer receive callbacks from test runs.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// Generic representing a type of callback.
|
||||
/// </typeparam>
|
||||
/// <param name="testCallbacks">The test callbacks to unregister.</param>
|
||||
public void UnregisterCallbacks<T>(T testCallbacks) where T : ICallbacks
|
||||
{
|
||||
if (testCallbacks == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(testCallbacks));
|
||||
}
|
||||
|
||||
m_CallbacksHolder.Remove(testCallbacks);
|
||||
}
|
||||
|
||||
internal void RetrieveTestList(ExecutionSettings executionSettings, Action<ITestAdaptor> callback)
|
||||
{
|
||||
if (executionSettings == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(executionSettings));
|
||||
}
|
||||
|
||||
var firstFilter = executionSettings.filters?.FirstOrDefault() ?? executionSettings.filter;
|
||||
RetrieveTestList(firstFilter.testMode, callback);
|
||||
}
|
||||
/// <summary>
|
||||
/// Retrieve the full test tree as ITestAdaptor for a given test mode. This is obsolete. Use TestRunnerApi.RetrieveTestTree instead.
|
||||
/// </summary>
|
||||
/// <param name="testMode"></param>
|
||||
/// <param name="callback"></param>
|
||||
public void RetrieveTestList(TestMode testMode, Action<ITestAdaptor> callback)
|
||||
{
|
||||
if (callback == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(callback));
|
||||
}
|
||||
|
||||
var platform = ParseTestMode(testMode);
|
||||
var testAssemblyProvider = new EditorLoadedTestAssemblyProvider(new EditorCompilationInterfaceProxy(), new EditorAssembliesProxy());
|
||||
var testAdaptorFactory = new TestAdaptorFactory();
|
||||
var testListCache = new TestListCache(testAdaptorFactory, new RemoteTestResultDataFactory(), TestListCacheData.instance);
|
||||
var testListProvider = new TestListProvider(testAssemblyProvider, new UnityTestAssemblyBuilder());
|
||||
var cachedTestListProvider = new CachingTestListProvider(testListProvider, testListCache, testAdaptorFactory);
|
||||
|
||||
var job = new TestListJob(cachedTestListProvider, platform, (testRoot) =>
|
||||
{
|
||||
callback(testRoot);
|
||||
});
|
||||
job.Start();
|
||||
}
|
||||
|
||||
internal static bool IsRunActive()
|
||||
{
|
||||
return RunData.instance.isRunning;
|
||||
}
|
||||
|
||||
private static TestPlatform ParseTestMode(TestMode testMode)
|
||||
{
|
||||
return (((testMode & TestMode.EditMode) == TestMode.EditMode) ? TestPlatform.EditMode : 0) | (((testMode & TestMode.PlayMode) == TestMode.PlayMode) ? TestPlatform.PlayMode : 0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 68993ba529ae04440916cb7c23bf3279
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,28 @@
|
|||
namespace UnityEditor.TestTools.TestRunner.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// The TestStatus enum indicates the test result status.
|
||||
/// </summary>
|
||||
public enum TestStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The test ran with an inconclusive result.
|
||||
/// </summary>
|
||||
Inconclusive,
|
||||
|
||||
/// <summary>
|
||||
/// The test was skipped.
|
||||
/// </summary>
|
||||
Skipped,
|
||||
|
||||
/// <summary>
|
||||
/// The test ran and passed.
|
||||
/// </summary>
|
||||
Passed,
|
||||
|
||||
/// <summary>
|
||||
/// The test ran and failed.
|
||||
/// </summary>
|
||||
Failed
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9ec94545c5b00344c9bd8e691f15d799
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,14 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: AssemblyTitle("UnityEditor.TestRunner")]
|
||||
[assembly: InternalsVisibleTo("Assembly-CSharp-Editor-testable")]
|
||||
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
|
||||
[assembly: InternalsVisibleTo("Unity.PerformanceTesting.Editor")]
|
||||
[assembly: InternalsVisibleTo("Unity.IntegrationTests")]
|
||||
[assembly: InternalsVisibleTo("UnityEditor.TestRunner.Tests")]
|
||||
[assembly: InternalsVisibleTo("Unity.PackageManagerUI.Develop.Editor")]
|
||||
[assembly: InternalsVisibleTo("Unity.PackageManagerUI.Develop.EditorTests")]
|
||||
[assembly: InternalsVisibleTo("Unity.PackageValidationSuite.Editor")]
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0")]
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9db19a04003fca7439552acd4de9baa1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7602252bdb82b8d45ae3483c3a00d3e1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace UnityEditor.TestRunner.CommandLineParser
|
||||
{
|
||||
internal class CommandLineOption : ICommandLineOption
|
||||
{
|
||||
Action<string> m_ArgAction;
|
||||
|
||||
public CommandLineOption(string argName, Action action)
|
||||
{
|
||||
ArgName = argName;
|
||||
m_ArgAction = s => action();
|
||||
}
|
||||
|
||||
public CommandLineOption(string argName, Action<string> action)
|
||||
{
|
||||
ArgName = argName;
|
||||
m_ArgAction = action;
|
||||
}
|
||||
|
||||
public CommandLineOption(string argName, Action<string[]> action)
|
||||
{
|
||||
ArgName = argName;
|
||||
m_ArgAction = s => action(SplitStringToArray(s));
|
||||
}
|
||||
|
||||
public string ArgName { get; private set; }
|
||||
|
||||
public void ApplyValue(string value)
|
||||
{
|
||||
m_ArgAction(value);
|
||||
}
|
||||
|
||||
static string[] SplitStringToArray(string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return value.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a3529368f4cd0424a89aa51080a16b06
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
|
||||
namespace UnityEditor.TestRunner.CommandLineParser
|
||||
{
|
||||
internal class CommandLineOptionSet
|
||||
{
|
||||
ICommandLineOption[] m_Options;
|
||||
|
||||
public CommandLineOptionSet(params ICommandLineOption[] options)
|
||||
{
|
||||
m_Options = options;
|
||||
}
|
||||
|
||||
public void Parse(string[] args)
|
||||
{
|
||||
var i = 0;
|
||||
while (i < args.Length)
|
||||
{
|
||||
var arg = args[i];
|
||||
if (!arg.StartsWith("-"))
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
string value = null;
|
||||
if (i + 1 < args.Length && !args[i + 1].StartsWith("-"))
|
||||
{
|
||||
value = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
|
||||
ApplyValueToMatchingOptions(arg, value);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyValueToMatchingOptions(string argName, string value)
|
||||
{
|
||||
foreach (var option in m_Options)
|
||||
{
|
||||
if ("-" + option.ArgName == argName)
|
||||
{
|
||||
option.ApplyValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 139c5eac101a4dc4fb3098e30c29f15e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
namespace UnityEditor.TestRunner.CommandLineParser
|
||||
{
|
||||
interface ICommandLineOption
|
||||
{
|
||||
string ArgName { get; }
|
||||
void ApplyValue(string value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f445ca0c614a846449fcd8ae648c24e2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b477d1f29b65a674e9d5cdab4eb72b01
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,134 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using UnityEditor.TestRunner.TestLaunchers;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
internal class Executer
|
||||
{
|
||||
private ITestRunnerApi m_TestRunnerApi;
|
||||
private ISettingsBuilder m_SettingsBuilder;
|
||||
private Action<string, object[]> m_LogErrorFormat;
|
||||
private Action<Exception> m_LogException;
|
||||
private Action<int> m_ExitEditorApplication;
|
||||
private Func<bool> m_ScriptCompilationFailedCheck;
|
||||
|
||||
public Executer(ITestRunnerApi testRunnerApi, ISettingsBuilder settingsBuilder, Action<string, object[]> logErrorFormat, Action<Exception> logException, Action<int> exitEditorApplication, Func<bool> scriptCompilationFailedCheck)
|
||||
{
|
||||
m_TestRunnerApi = testRunnerApi;
|
||||
m_SettingsBuilder = settingsBuilder;
|
||||
m_LogErrorFormat = logErrorFormat;
|
||||
m_LogException = logException;
|
||||
m_ExitEditorApplication = exitEditorApplication;
|
||||
m_ScriptCompilationFailedCheck = scriptCompilationFailedCheck;
|
||||
}
|
||||
|
||||
internal void InitializeAndExecuteRun(string[] commandLineArgs)
|
||||
{
|
||||
Api.ExecutionSettings executionSettings;
|
||||
try
|
||||
{
|
||||
executionSettings = m_SettingsBuilder.BuildApiExecutionSettings(commandLineArgs);
|
||||
if (executionSettings.targetPlatform.HasValue)
|
||||
RemotePlayerLogController.instance.SetBuildTarget(executionSettings.targetPlatform.Value);
|
||||
}
|
||||
catch (SetupException exception)
|
||||
{
|
||||
HandleSetupException(exception);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Debug.Log("Executing tests with settings: " + ExecutionSettingsToString(executionSettings));
|
||||
m_TestRunnerApi.Execute(executionSettings);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
m_LogException(exception);
|
||||
m_ExitEditorApplication((int)ReturnCodes.RunError);
|
||||
}
|
||||
}
|
||||
|
||||
internal ExecutionSettings BuildExecutionSettings(string[] commandLineArgs)
|
||||
{
|
||||
return m_SettingsBuilder.BuildExecutionSettings(commandLineArgs);
|
||||
}
|
||||
|
||||
internal enum ReturnCodes
|
||||
{
|
||||
Ok = 0,
|
||||
Failed = 2,
|
||||
RunError = 3,
|
||||
PlatformNotFoundReturnCode = 4
|
||||
}
|
||||
|
||||
internal void SetUpCallbacks(ExecutionSettings executionSettings)
|
||||
{
|
||||
RemotePlayerLogController.instance.SetLogsDirectory(executionSettings.DeviceLogsDirectory);
|
||||
|
||||
var resultSavingCallback = ScriptableObject.CreateInstance<ResultsSavingCallbacks>();
|
||||
resultSavingCallback.m_ResultFilePath = executionSettings.TestResultsFile;
|
||||
|
||||
var logSavingCallback = ScriptableObject.CreateInstance<LogSavingCallbacks>();
|
||||
|
||||
m_TestRunnerApi.RegisterCallbacks(resultSavingCallback);
|
||||
m_TestRunnerApi.RegisterCallbacks(logSavingCallback);
|
||||
m_TestRunnerApi.RegisterCallbacks(ScriptableObject.CreateInstance<ExitCallbacks>(), -10);
|
||||
}
|
||||
|
||||
internal void ExitOnCompileErrors()
|
||||
{
|
||||
if (m_ScriptCompilationFailedCheck())
|
||||
{
|
||||
var handling = s_ExceptionHandlingMapping.First(h => h.m_ExceptionType == SetupException.ExceptionType.ScriptCompilationFailed);
|
||||
m_LogErrorFormat(handling.m_Message, new object[0]);
|
||||
m_ExitEditorApplication(handling.m_ReturnCode);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleSetupException(SetupException exception)
|
||||
{
|
||||
ExceptionHandling handling = s_ExceptionHandlingMapping.FirstOrDefault(h => h.m_ExceptionType == exception.Type) ?? new ExceptionHandling(exception.Type, "Unknown command line test run error. " + exception.Type, ReturnCodes.RunError);
|
||||
m_LogErrorFormat(handling.m_Message, exception.Details);
|
||||
m_ExitEditorApplication(handling.m_ReturnCode);
|
||||
}
|
||||
|
||||
private class ExceptionHandling
|
||||
{
|
||||
internal SetupException.ExceptionType m_ExceptionType;
|
||||
internal string m_Message;
|
||||
internal int m_ReturnCode;
|
||||
public ExceptionHandling(SetupException.ExceptionType exceptionType, string message, ReturnCodes returnCode)
|
||||
{
|
||||
m_ExceptionType = exceptionType;
|
||||
m_Message = message;
|
||||
m_ReturnCode = (int)returnCode;
|
||||
}
|
||||
}
|
||||
|
||||
static ExceptionHandling[] s_ExceptionHandlingMapping = new[]
|
||||
{
|
||||
new ExceptionHandling(SetupException.ExceptionType.ScriptCompilationFailed, "Scripts had compilation errors.", ReturnCodes.RunError),
|
||||
new ExceptionHandling(SetupException.ExceptionType.PlatformNotFound, "Test platform not found ({0}).", ReturnCodes.PlatformNotFoundReturnCode),
|
||||
new ExceptionHandling(SetupException.ExceptionType.TestSettingsFileNotFound, "Test settings file not found at {0}.", ReturnCodes.RunError)
|
||||
};
|
||||
|
||||
private static string ExecutionSettingsToString(Api.ExecutionSettings executionSettings)
|
||||
{
|
||||
if (executionSettings == null)
|
||||
{
|
||||
return "none";
|
||||
}
|
||||
|
||||
if (executionSettings.filters == null || executionSettings.filters.Length == 0)
|
||||
{
|
||||
return "no filter";
|
||||
}
|
||||
|
||||
return "test mode = " + executionSettings.filters[0].testMode;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 083c6a3a5426382449369ddc12b691d8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
[Serializable]
|
||||
internal class ExecutionSettings
|
||||
{
|
||||
public string TestResultsFile;
|
||||
public string DeviceLogsDirectory;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c3a75354f6ceac94ca15ca9d96593290
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
[Serializable]
|
||||
internal class ExitCallbacks : ScriptableObject, IErrorCallbacks
|
||||
{
|
||||
internal static bool preventExit;
|
||||
|
||||
public void RunFinished(ITestResultAdaptor testResults)
|
||||
{
|
||||
if (preventExit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ExitCallbacksDataHolder.instance.AnyTestsExecuted)
|
||||
{
|
||||
Debug.LogFormat(LogType.Warning, LogOption.NoStacktrace, null, "No tests were executed");
|
||||
}
|
||||
|
||||
EditorApplication.Exit(ExitCallbacksDataHolder.instance.RunFailed ? (int)Executer.ReturnCodes.Failed : (int)Executer.ReturnCodes.Ok);
|
||||
}
|
||||
|
||||
public void TestStarted(ITestAdaptor test)
|
||||
{
|
||||
if (!test.IsSuite)
|
||||
{
|
||||
ExitCallbacksDataHolder.instance.AnyTestsExecuted = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void TestFinished(ITestResultAdaptor result)
|
||||
{
|
||||
if (!result.Test.IsSuite && (result.TestStatus == TestStatus.Failed || result.TestStatus == TestStatus.Inconclusive))
|
||||
{
|
||||
ExitCallbacksDataHolder.instance.RunFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void RunStarted(ITestAdaptor testsToRun)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnError(string message)
|
||||
{
|
||||
EditorApplication.Exit((int)Executer.ReturnCodes.RunError);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1adaa8dcc4fda3d4cb4d3c8e0cb65d12
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
internal class ExitCallbacksDataHolder : ScriptableSingleton<ExitCallbacksDataHolder>
|
||||
{
|
||||
[SerializeField]
|
||||
public bool AnyTestsExecuted;
|
||||
[SerializeField]
|
||||
public bool RunFailed;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: aab045daa0ad4b01843dcf44013d9653
|
||||
timeCreated: 1605189497
|
|
@ -0,0 +1,10 @@
|
|||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
interface ISettingsBuilder
|
||||
{
|
||||
Api.ExecutionSettings BuildApiExecutionSettings(string[] commandLineArgs);
|
||||
ExecutionSettings BuildExecutionSettings(string[] commandLineArgs);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8a13cbeb2099aca47bb456f49845f86c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using UnityEditor.TestRunner.TestLaunchers;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
[Serializable]
|
||||
internal class LogSavingCallbacks : ScriptableObject, ICallbacks
|
||||
{
|
||||
public void RunStarted(ITestAdaptor testsToRun)
|
||||
{
|
||||
RemotePlayerLogController.instance.StartLogWriters();
|
||||
}
|
||||
|
||||
public virtual void RunFinished(ITestResultAdaptor testResults)
|
||||
{
|
||||
RemotePlayerLogController.instance.StopLogWriters();
|
||||
}
|
||||
|
||||
public void TestStarted(ITestAdaptor test)
|
||||
{
|
||||
}
|
||||
|
||||
public void TestFinished(ITestResultAdaptor result)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8d20eedbe40f0ce41a4c4f633f225de8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,92 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor.DeploymentTargets;
|
||||
using UnityEditor.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
internal class LogWriter : IDisposable
|
||||
{
|
||||
private string m_LogsDirectory;
|
||||
private string m_DeviceID;
|
||||
private Dictionary<string, StreamWriter> m_LogStreams;
|
||||
private DeploymentTargetLogger m_Logger;
|
||||
|
||||
internal LogWriter(string logsDirectory, string deviceID, DeploymentTargetLogger logger)
|
||||
{
|
||||
m_LogStreams = new Dictionary<string, StreamWriter>();
|
||||
m_Logger = logger;
|
||||
m_LogsDirectory = logsDirectory;
|
||||
m_DeviceID = deviceID;
|
||||
|
||||
logger.logMessage += WriteLogToFile;
|
||||
}
|
||||
|
||||
private void WriteLogToFile(string id, string logLine)
|
||||
{
|
||||
StreamWriter logStream;
|
||||
var streamExists = m_LogStreams.TryGetValue(id, out logStream);
|
||||
if (!streamExists)
|
||||
{
|
||||
var filePath = GetLogFilePath(m_LogsDirectory, m_DeviceID, id);
|
||||
logStream = CreateLogFile(filePath);
|
||||
|
||||
m_LogStreams.Add(id, logStream);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (logLine != null)
|
||||
logStream.WriteLine(logLine);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"Writing {id} log failed.");
|
||||
Debug.LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
m_Logger.Stop();
|
||||
foreach (var logStream in m_LogStreams)
|
||||
{
|
||||
logStream.Value.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
private StreamWriter CreateLogFile(string path)
|
||||
{
|
||||
Debug.LogFormat(LogType.Log, LogOption.NoStacktrace, null, "Creating {0} device log: {1}", m_DeviceID, path);
|
||||
StreamWriter streamWriter = null;
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(path))
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
|
||||
streamWriter = File.CreateText(path);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"Creating device log {path} file failed.");
|
||||
Debug.LogException(ex);
|
||||
}
|
||||
|
||||
return streamWriter;
|
||||
}
|
||||
|
||||
private string GetLogFilePath(string lgosDirectory, string deviceID, string logID)
|
||||
{
|
||||
var fileName = "Device-" + deviceID + "-" + logID + ".txt";
|
||||
fileName = string.Join("_", fileName.Split(Path.GetInvalidFileNameChars()));
|
||||
return Paths.Combine(lgosDirectory, fileName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 05778dd1de4433d418793b6f3d3c18cf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEditor.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
[Serializable]
|
||||
internal class ResultsSavingCallbacks : ScriptableObject, ICallbacks
|
||||
{
|
||||
[SerializeField]
|
||||
public string m_ResultFilePath;
|
||||
|
||||
public ResultsSavingCallbacks()
|
||||
{
|
||||
this.m_ResultFilePath = GetDefaultResultFilePath();
|
||||
}
|
||||
|
||||
public void RunStarted(ITestAdaptor testsToRun)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void RunFinished(ITestResultAdaptor testResults)
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_ResultFilePath))
|
||||
{
|
||||
m_ResultFilePath = GetDefaultResultFilePath();
|
||||
}
|
||||
|
||||
var resultWriter = new ResultsWriter();
|
||||
resultWriter.WriteResultToFile(testResults, m_ResultFilePath);
|
||||
}
|
||||
|
||||
public void TestStarted(ITestAdaptor test)
|
||||
{
|
||||
}
|
||||
|
||||
public void TestFinished(ITestResultAdaptor result)
|
||||
{
|
||||
}
|
||||
|
||||
private static string GetDefaultResultFilePath()
|
||||
{
|
||||
var fileName = "TestResults-" + DateTime.Now.Ticks + ".xml";
|
||||
var projectPath = Directory.GetCurrentDirectory();
|
||||
return Paths.Combine(projectPath, fileName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ef563c5a6ecf64d4193dc144cb7d472a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,103 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
internal class ResultsWriter
|
||||
{
|
||||
private const string k_nUnitVersion = "3.5.0.0";
|
||||
|
||||
private const string k_TestRunNode = "test-run";
|
||||
private const string k_Id = "id";
|
||||
private const string k_Testcasecount = "testcasecount";
|
||||
private const string k_Result = "result";
|
||||
private const string k_Total = "total";
|
||||
private const string k_Passed = "passed";
|
||||
private const string k_Failed = "failed";
|
||||
private const string k_Inconclusive = "inconclusive";
|
||||
private const string k_Skipped = "skipped";
|
||||
private const string k_Asserts = "asserts";
|
||||
private const string k_EngineVersion = "engine-version";
|
||||
private const string k_ClrVersion = "clr-version";
|
||||
private const string k_StartTime = "start-time";
|
||||
private const string k_EndTime = "end-time";
|
||||
private const string k_Duration = "duration";
|
||||
|
||||
private const string k_TimeFormat = "u";
|
||||
|
||||
public void WriteResultToFile(ITestResultAdaptor result, string filePath)
|
||||
{
|
||||
Debug.LogFormat(LogType.Log, LogOption.NoStacktrace, null, "Saving results to: {0}", filePath);
|
||||
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(filePath))
|
||||
{
|
||||
CreateDirectory(filePath);
|
||||
}
|
||||
|
||||
using (var fileStream = File.CreateText(filePath))
|
||||
{
|
||||
WriteResultToStream(result, fileStream);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError("Saving result file failed.");
|
||||
Debug.LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
void CreateDirectory(string filePath)
|
||||
{
|
||||
var driectoryPath = Path.GetDirectoryName(filePath);
|
||||
if (!String.IsNullOrEmpty(driectoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(driectoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteResultToStream(ITestResultAdaptor result, StreamWriter streamWriter, XmlWriterSettings settings = null)
|
||||
{
|
||||
settings = settings ?? new XmlWriterSettings();
|
||||
settings.Indent = true;
|
||||
settings.NewLineOnAttributes = false;
|
||||
|
||||
using (var xmlWriter = XmlWriter.Create(streamWriter, settings))
|
||||
{
|
||||
WriteResultsToXml(result, xmlWriter);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteResultsToXml(ITestResultAdaptor result, XmlWriter xmlWriter)
|
||||
{
|
||||
// XML format as specified at https://github.com/nunit/docs/wiki/Test-Result-XML-Format
|
||||
|
||||
var testRunNode = new TNode(k_TestRunNode);
|
||||
|
||||
testRunNode.AddAttribute(k_Id, "2");
|
||||
testRunNode.AddAttribute(k_Testcasecount, (result.PassCount + result.FailCount + result.SkipCount + result.InconclusiveCount).ToString());
|
||||
testRunNode.AddAttribute(k_Result, result.ResultState.ToString());
|
||||
testRunNode.AddAttribute(k_Total, (result.PassCount + result.FailCount + result.SkipCount + result.InconclusiveCount).ToString());
|
||||
testRunNode.AddAttribute(k_Passed, result.PassCount.ToString());
|
||||
testRunNode.AddAttribute(k_Failed, result.FailCount.ToString());
|
||||
testRunNode.AddAttribute(k_Inconclusive, result.InconclusiveCount.ToString());
|
||||
testRunNode.AddAttribute(k_Skipped, result.SkipCount.ToString());
|
||||
testRunNode.AddAttribute(k_Asserts, result.AssertCount.ToString());
|
||||
testRunNode.AddAttribute(k_EngineVersion, k_nUnitVersion);
|
||||
testRunNode.AddAttribute(k_ClrVersion, Environment.Version.ToString());
|
||||
testRunNode.AddAttribute(k_StartTime, result.StartTime.ToString(k_TimeFormat));
|
||||
testRunNode.AddAttribute(k_EndTime, result.EndTime.ToString(k_TimeFormat));
|
||||
testRunNode.AddAttribute(k_Duration, result.Duration.ToString());
|
||||
|
||||
var resultNode = result.ToXml();
|
||||
testRunNode.ChildNodes.Add(resultNode);
|
||||
|
||||
testRunNode.WriteTo(xmlWriter);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 29d603e0a726a9043b3503112271844a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,8 @@
|
|||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
internal class RunData : ScriptableSingleton<RunData>
|
||||
{
|
||||
public bool isRunning;
|
||||
public ExecutionSettings executionSettings;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3f8c1075884df0249b80e23a0598f9c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,29 @@
|
|||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
internal class RunSettings : ITestRunSettings
|
||||
{
|
||||
private ITestSettings m_TestSettings;
|
||||
public RunSettings(ITestSettings testSettings)
|
||||
{
|
||||
this.m_TestSettings = testSettings;
|
||||
}
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
if (m_TestSettings != null)
|
||||
{
|
||||
m_TestSettings.SetupProjectParameters();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (m_TestSettings != null)
|
||||
{
|
||||
m_TestSettings.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 59d3f5586b341a74c84c8f72144a4568
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,192 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor.TestRunner.CommandLineParser;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEditor.TestTools.TestRunner.GUI;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
internal class SettingsBuilder : ISettingsBuilder
|
||||
{
|
||||
private ITestSettingsDeserializer m_TestSettingsDeserializer;
|
||||
private Action<string> m_LogAction;
|
||||
private Action<string> m_LogWarningAction;
|
||||
private Func<string, bool> m_FileExistsCheck;
|
||||
private Func<bool> m_ScriptCompilationFailedCheck;
|
||||
public SettingsBuilder(ITestSettingsDeserializer testSettingsDeserializer, Action<string> logAction, Action<string> logWarningAction, Func<string, bool> fileExistsCheck, Func<bool> scriptCompilationFailedCheck)
|
||||
{
|
||||
m_LogAction = logAction;
|
||||
m_LogWarningAction = logWarningAction;
|
||||
m_FileExistsCheck = fileExistsCheck;
|
||||
m_ScriptCompilationFailedCheck = scriptCompilationFailedCheck;
|
||||
m_TestSettingsDeserializer = testSettingsDeserializer;
|
||||
}
|
||||
|
||||
public Api.ExecutionSettings BuildApiExecutionSettings(string[] commandLineArgs)
|
||||
{
|
||||
var quit = false;
|
||||
string testPlatform = TestMode.EditMode.ToString();
|
||||
string[] testFilters = null;
|
||||
string[] testCategories = null;
|
||||
string testSettingsFilePath = null;
|
||||
int testRepetitions = 1;
|
||||
int? playerHeartbeatTimeout = null;
|
||||
bool runSynchronously = false;
|
||||
string[] testAssemblyNames = null;
|
||||
string buildPlayerPath = string.Empty;
|
||||
|
||||
|
||||
var optionSet = new CommandLineOptionSet(
|
||||
new CommandLineOption("quit", () => { quit = true; }),
|
||||
new CommandLineOption("testPlatform", platform => { testPlatform = platform; }),
|
||||
new CommandLineOption("editorTestsFilter", filters => { testFilters = filters; }),
|
||||
new CommandLineOption("testFilter", filters => { testFilters = filters; }),
|
||||
new CommandLineOption("editorTestsCategories", catagories => { testCategories = catagories; }),
|
||||
new CommandLineOption("testCategory", catagories => { testCategories = catagories; }),
|
||||
new CommandLineOption("testSettingsFile", settingsFilePath => { testSettingsFilePath = settingsFilePath; }),
|
||||
new CommandLineOption("testRepetitions", reps => { testRepetitions = int.Parse(reps); }),
|
||||
new CommandLineOption("playerHeartbeatTimeout", timeout => { playerHeartbeatTimeout = int.Parse(timeout); }),
|
||||
new CommandLineOption("runSynchronously", () => { runSynchronously = true; }),
|
||||
new CommandLineOption("assemblyNames", assemblyNames => { testAssemblyNames = assemblyNames; }),
|
||||
new CommandLineOption("buildPlayerPath", buildPath => { buildPlayerPath = buildPath; })
|
||||
);
|
||||
optionSet.Parse(commandLineArgs);
|
||||
|
||||
DisplayQuitWarningIfQuitIsGiven(quit);
|
||||
|
||||
CheckForScriptCompilationErrors();
|
||||
|
||||
LogParametersForRun(testPlatform, testFilters, testCategories, testSettingsFilePath);
|
||||
|
||||
var testSettings = GetTestSettings(testSettingsFilePath);
|
||||
|
||||
var filter = new Filter()
|
||||
{
|
||||
groupNames = testFilters,
|
||||
categoryNames = testCategories,
|
||||
assemblyNames = testAssemblyNames
|
||||
};
|
||||
|
||||
var buildTarget = SetFilterAndGetBuildTarget(testPlatform, filter);
|
||||
|
||||
RerunCallbackData.instance.runFilters = new []{new UITestRunnerFilter()
|
||||
{
|
||||
categoryNames = filter.categoryNames,
|
||||
groupNames = filter.groupNames,
|
||||
testRepetitions = testRepetitions
|
||||
}};
|
||||
|
||||
RerunCallbackData.instance.testMode = filter.testMode;
|
||||
|
||||
var settings = new Api.ExecutionSettings()
|
||||
{
|
||||
filters = new []{filter},
|
||||
overloadTestRunSettings = new RunSettings(testSettings),
|
||||
targetPlatform = buildTarget,
|
||||
runSynchronously = runSynchronously,
|
||||
playerSavePath = buildPlayerPath
|
||||
};
|
||||
|
||||
if (playerHeartbeatTimeout != null)
|
||||
{
|
||||
settings.playerHeartbeatTimeout = playerHeartbeatTimeout.Value;
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
public ExecutionSettings BuildExecutionSettings(string[] commandLineArgs)
|
||||
{
|
||||
string resultFilePath = null;
|
||||
string deviceLogsDirectory = null;
|
||||
|
||||
var optionSet = new CommandLineOptionSet(
|
||||
new CommandLineOption("editorTestsResultFile", filePath => { resultFilePath = filePath; }),
|
||||
new CommandLineOption("testResults", filePath => { resultFilePath = filePath; }),
|
||||
new CommandLineOption("deviceLogs", dirPath => { deviceLogsDirectory = dirPath; })
|
||||
);
|
||||
optionSet.Parse(commandLineArgs);
|
||||
|
||||
return new ExecutionSettings()
|
||||
{
|
||||
TestResultsFile = resultFilePath,
|
||||
DeviceLogsDirectory = deviceLogsDirectory
|
||||
};
|
||||
}
|
||||
|
||||
void DisplayQuitWarningIfQuitIsGiven(bool quitIsGiven)
|
||||
{
|
||||
if (quitIsGiven)
|
||||
{
|
||||
m_LogWarningAction("Running tests from command line arguments will not work when \"quit\" is specified.");
|
||||
}
|
||||
}
|
||||
|
||||
void CheckForScriptCompilationErrors()
|
||||
{
|
||||
if (m_ScriptCompilationFailedCheck())
|
||||
{
|
||||
throw new SetupException(SetupException.ExceptionType.ScriptCompilationFailed);
|
||||
}
|
||||
}
|
||||
|
||||
void LogParametersForRun(string testPlatform, string[] testFilters, string[] testCategories, string testSettingsFilePath)
|
||||
{
|
||||
m_LogAction("Running tests for " + testPlatform);
|
||||
if (testFilters != null && testFilters.Length > 0)
|
||||
{
|
||||
m_LogAction("With test filter: " + string.Join(", ", testFilters));
|
||||
}
|
||||
if (testCategories != null && testCategories.Length > 0)
|
||||
{
|
||||
m_LogAction("With test categories: " + string.Join(", ", testCategories));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(testSettingsFilePath))
|
||||
{
|
||||
m_LogAction("With test settings file: " + testSettingsFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
ITestSettings GetTestSettings(string testSettingsFilePath)
|
||||
{
|
||||
ITestSettings testSettings = null;
|
||||
if (!string.IsNullOrEmpty(testSettingsFilePath))
|
||||
{
|
||||
if (!m_FileExistsCheck(testSettingsFilePath))
|
||||
{
|
||||
throw new SetupException(SetupException.ExceptionType.TestSettingsFileNotFound, testSettingsFilePath);
|
||||
}
|
||||
|
||||
testSettings = m_TestSettingsDeserializer.GetSettingsFromJsonFile(testSettingsFilePath);
|
||||
}
|
||||
return testSettings;
|
||||
}
|
||||
|
||||
static BuildTarget? SetFilterAndGetBuildTarget(string testPlatform, Filter filter)
|
||||
{
|
||||
BuildTarget? buildTarget = null;
|
||||
if (testPlatform.ToLower() == "editmode")
|
||||
{
|
||||
filter.testMode = TestMode.EditMode;
|
||||
}
|
||||
else if (testPlatform.ToLower() == "playmode")
|
||||
{
|
||||
filter.testMode = TestMode.PlayMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
buildTarget = (BuildTarget)Enum.Parse(typeof(BuildTarget), testPlatform, true);
|
||||
|
||||
filter.testMode = TestMode.PlayMode;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
throw new SetupException(SetupException.ExceptionType.PlatformNotFound, testPlatform);
|
||||
}
|
||||
}
|
||||
return buildTarget;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b7468a027a77337478e133b40b42b4f9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
internal class SetupException : Exception
|
||||
{
|
||||
public ExceptionType Type { get; }
|
||||
public object[] Details { get; }
|
||||
|
||||
public SetupException(ExceptionType type, params object[] details)
|
||||
{
|
||||
Type = type;
|
||||
Details = details;
|
||||
}
|
||||
|
||||
public enum ExceptionType
|
||||
{
|
||||
ScriptCompilationFailed,
|
||||
PlatformNotFound,
|
||||
TestSettingsFileNotFound,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 63572993f2104574099a48392460b211
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,82 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor.TestRunner.CommandLineParser;
|
||||
using UnityEditor.TestTools.TestRunner.Api;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Compilation;
|
||||
using System.Linq;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.TestTools.TestRunner.CommandLineTest
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
static class TestStarter
|
||||
{
|
||||
static TestStarter()
|
||||
{
|
||||
if (!ShouldRunTests())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (EditorApplication.isCompiling)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (RunData.instance.isRunning)
|
||||
{
|
||||
executer.ExitOnCompileErrors();
|
||||
executer.SetUpCallbacks(RunData.instance.executionSettings);
|
||||
return;
|
||||
}
|
||||
|
||||
EditorApplication.update += UpdateWatch;
|
||||
}
|
||||
|
||||
static void UpdateWatch()
|
||||
{
|
||||
EditorApplication.update -= UpdateWatch;
|
||||
|
||||
if (RunData.instance.isRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RunData.instance.isRunning = true;
|
||||
var commandLineArgs = Environment.GetCommandLineArgs();
|
||||
RunData.instance.executionSettings = executer.BuildExecutionSettings(commandLineArgs);
|
||||
executer.SetUpCallbacks(RunData.instance.executionSettings);
|
||||
executer.InitializeAndExecuteRun(commandLineArgs);
|
||||
}
|
||||
|
||||
static bool ShouldRunTests()
|
||||
{
|
||||
var shouldRunTests = false;
|
||||
var optionSet = new CommandLineOptionSet(
|
||||
new CommandLineOption("runTests", () => { shouldRunTests = true; }),
|
||||
new CommandLineOption("runEditorTests", () => { shouldRunTests = true; })
|
||||
);
|
||||
optionSet.Parse(Environment.GetCommandLineArgs());
|
||||
return shouldRunTests;
|
||||
}
|
||||
|
||||
static Executer s_Executer;
|
||||
|
||||
static Executer executer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_Executer == null)
|
||||
{
|
||||
Func<bool> compilationCheck = () => EditorUtility.scriptCompilationFailed;
|
||||
Action<string> actionLogger = (string msg) => { Debug.LogFormat(LogType.Log, LogOption.NoStacktrace, null, msg); };
|
||||
var apiSettingsBuilder = new SettingsBuilder(new TestSettingsDeserializer(() => new TestSettings()), actionLogger, Debug.LogWarning, File.Exists, compilationCheck);
|
||||
s_Executer = new Executer(ScriptableObject.CreateInstance<TestRunnerApi>(), apiSettingsBuilder, Debug.LogErrorFormat, Debug.LogException, EditorApplication.Exit, compilationCheck);
|
||||
}
|
||||
|
||||
return s_Executer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4d616d1a494edd144b262cf6cd5e5fda
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue