Skip to content

Commit 53a4d9e

Browse files
marchello2000ZiyunShang
authored andcommitted
Merge UpCodes improvements (#87)
* Group tests by model with the `GroupByModel` param * Tests in same fixture with same model path will run with the same model (without reopening the model) * Additional fixes: - Remember the directory for file pickers - Automatically set the working/results directory - Automatically infer the version of Revit to use from the assembly (based on the RevitAPI linked against) - Clean up a bunch of stale variables, update parts to modern C# standards - Fix by category grouping to show tests that aren't in a category * Nuget package definition * Fix the test runner such that it spits out an error when a text model is not found * Various UI improvements: * Show how many tests pass/fail after a test run * Auto expand tree with failing tests * fixup! Merge pull request #4 from marchello2000/mark/failing_tests_indicator * Clarity improvements: * Add `ERROR` and `WARNING` to appropriate WriteLines to clearly highlight when something goes wrong * Compact the UI a bit and give more room to console logger * Clearly state how many tests pass/fail/skip in the last run in the console log for the gui * Nuget version update * Add ability to marshal console logs from unit test * Spit out information to console as the test complete * Add ability to clear in the console box * Update nuspec version and readme * Add missing empty.rfa file to the nuget package * Porting fix for #71 * Properly fail tests whose model isn't found * Fix null deref in console mode * Add ability to specify wildcard for a model file name The way it's implemented is as follows: 1. During assembly load, check if a test has a wildcard for the model, e.g. ``` [TestModel(@"C:\RevitModels\test_models\*.rvt")] ``` or ``` [TestModel(@"C:\RevitModels\test_models\*.rfa")] ``` 2. Enumerate all files that match the wildcard in the specified directory 3. For each model file found, create a separate entry for the current test with this model * Add proper error handling for wildcard models Add error when no model files are found with a given wildcard * Initialize output redirector earlier to catch command line arguments * Add a timeout to Revit termination In case Revit doesn't terminate within a timeframe (45s) it is force terminated after test run is complete (only works for -continuous right now) * Update README.md * Automated build with AppVeyor * Use Nugets for Revit dependencies (e.g. RevitAPI.dll and RevitAddingUtility.dll) * Remove platform architecture warnings * Remove some unused variables and other warnings from build * Remove double definition of NUnitResultTypes * Add ability to override Revit installation enumeration during UnitTests for CI machines with Revit * Update Nuget package and add AppVeyor.yaml file * Fix automatic nuget publishing * Add instructions on how to run RTF in CI * Pull request fixups Revert to ReflectionOnlyLoadFrom for assembly loader because Dynamo relies on it * PR Feedback: * Ensure all new methods/classes have XML docs * Ensure all memebers have access modifiers * Update readme * PR Feedback: do not distribute nunit/prism/etc libraries Using Costura to merge the needed binaries into the RTF assemblies such that they don't need to be redistributed without correct nuget usage * Adding license info for used dlls
1 parent de54935 commit 53a4d9e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1919
-1206
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ x64/
4949
build/
5050
[Bb]in/
5151
[Oo]bj/
52+
.vs/
5253

5354
# MSTest test Results
5455
[Tt]est[Rr]esult*/
@@ -130,7 +131,7 @@ publish/
130131

131132
# NuGet Packages Directory
132133
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
133-
#packages/
134+
packages/
134135

135136
# Windows Azure Build Output
136137
csx

README.md

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
1-
## RevitTestFramework
1+
# RevitTestFramework
22

3-
The Revit Test Framework (RTF) allows you to conduct remote unit testing on Revit. RTF takes care of creating a journal file for running revit which can specify a model to start Revit, and a specific test or fixture of tests to Run. You can even specify a model to open before testing and RTF will do that as well.
3+
The Revit Test Framework (RTF) allows you to conduct remote unit testing on Revit. RTF takes care of creating a journal file for running revit which can specify a model to start Revit, and a specific test or fixture of tests to run. You can even specify a model to open before testing and RTF will do that as well.
4+
5+
[![Build status](https://ci.appveyor.com/api/projects/status/oqd23280efmaimmm/branch/mark/Revit2019?svg=true)](https://ci.appveyor.com/project/marchello2000/revittestframework/branch/mark/Revit2019)
6+
[![NuGet](https://img.shields.io/nuget/v/revittestframework.svg)](https://www.nuget.org/packages/revittestframework)
47

58
## Applications
69

7-
##### RevitTestFrameworkConsole.exe
10+
There are two ways to run RTF:
11+
* **RevitTestFrameworkConsole.exe**
12+
A Console application to run test from a command line
13+
* **RevitTestFrameworkGUI.exe**
14+
A GUI application that allows easy selection of tests to run and check results
15+
16+
Both options run the tests in the same way
17+
18+
### RevitTestFrameworkConsole.exe
819
A console application which allows running RTF without a user interface. If you'd like to learn more about the command line options for RTF, you can simply type "RevitTestFrameworkConsole -h" and you'll get something like this:
920
```
10-
Options:
21+
Options:
22+
1123
--dir=[VALUE] The full path to the working directory. The working directory is the directory in which RTF will generate the journal and the addin to Run Revit. Revit's run-by-journal capability requires that all addins which need to be loaded are in the same directory as the journal file. So, if you're testing other addins on top of Revit using RTF, you'll need to put those addins in whatever directory you specify as the working directory.
1224
-a, --assembly=[VALUE] The full path to the assembly containing your tests.
1325
-r, --results=[VALUE] This is the full path to an .xml file that will contain the results.
@@ -21,38 +33,66 @@ A console application which allows running RTF without a user interface. If you'
2133
--dry Conduct a dry run. (OPTIONAL)
2234
-x, --clean Cleanup journal files after test completion. (OPTIONAL)
2335
--continuous Run all selected tests in one Revit session. (OPTIONAL)
36+
--groupByModel Run tests with same model without reopening the model for faster execution, requires --continuous. (OPTIONAL)
2437
--time The time, in milliseconds, after which RTF will close the testing process automatically. (OPTIONAL)
2538
-d, --debug Should RTF attempt to attach to a debugger?. (OPTIONAL)
2639
-h, --help Show this message and exit. (OPTIONAL)
2740
```
2841

29-
##### RevitTestFrameworkGUI.exe
30-
Provides a visual interface for you to choose tests from a treeview and to visualize the results of the tests as they are run. The same settings provided in the command line argument help above are available in the UI. The UI also allows you to save your testing session.
42+
As an example, the following command:
43+
```
44+
RevitTestFrameworkConsole.exe --dir C:\MyTestDir -a MyTest.dll -r MyTestResults.xml -revit:"C:\Program Files\Autodesk\Revit 2019\Revit.exe" --continuous
45+
```
46+
will execute all tests in `MyTest.dll` located in `C:\MyTestDir` and place all results in `MyTestResults.xml` (in the same folder). It will use Revit 2019 as specified and will run all tests without shutting down Revit.
3147

32-
The input fields to set the test assembly, the working directory, and the results file, as well as the tree view where available tests are displayed, support dragging and dropping of files and folders.
48+
The results of the run as well as any `Console.WriteLine` or `Console.Error.WriteLine` from test will be shown in the command window and written ot the results xml file, e.g.:
3349

34-
![Image](https://user-images.githubusercontent.com/3942418/28271251-0822ae5c-6ad6-11e7-8028-4f2f5c03823e.png)
50+
```
51+
Reading assembly: D:\MyTestDir\MyTest.dll
52+
Loaded test: Name: UnitTest1, Model Path: D:\MyTestDir\MyModel1.rvt (D:\MyTestDir\MyModel1.rvt)
53+
Loaded test: Name: UnitTest2, Model Path: D:\MyTestDir\MyModel2.rvt (D:\MyTestDir\MyModel2.rvt)
54+
Running D:\Projects\UpCodes\upcodes_revit\Tests\2019\bin\Debug\RTF_Batch_Test.txt
55+
Running UnitTest1 in BasicTests
56+
Success: UnitTest1 in BasicTests
57+
58+
Running UnitTest2 in BasicTests
59+
Success: UnitTest2 in BasicTests
60+
61+
Waiting for Revit to terminate
62+
WARNING: One or more journal files could not be deleted.
63+
```
3564

36-
`File` - For saving and loading your local RTF config.
65+
The warning about some journal files not being deleted can be safely ignored.
3766

38-
`Test Assembly` - Path to assembly containing the tests to run. E.g. RevitNodesTests.dll, RevitSystemTests.dll, RevitServicesTests.dll.
67+
### RevitTestFrameworkGUI.exe
68+
Provides a visual interface for you to choose tests from a treeview and to visualize the results of the tests as they are run. The same settings provided in the command line argument help above are available in the UI. The UI also allows you to save your testing session.
3969

40-
`Results File Path` - Path to the xml file containing the tests results. If it's an existing file, RTF will replace it.
70+
The input fields to set the test assembly, the working directory, and the results file, as well as the tree view where available tests are displayed, support dragging and dropping of files and folders.
4171

42-
`Working Directory` - Path to where the testing Revit files are.
72+
RevitTestFrameworkGUI.exe can also take an argument for the test assembly path and will automatically fill all values on start so you can just hit `Run`.
4373

44-
`Additional Resolution Directories` - Path to find Dynamo Core location when it is not set in the `Dynamo.Config` in DynamoRevit bin folder.
74+
![RTF](images/RTF_UI.PNG)
4575

76+
`File` - For saving and loading your local RTF config.
77+
`Test Assembly` - Path to assembly containing the tests to run. E.g. RevitNodesTests.dll, RevitSystemTests.dll, RevitServicesTests.dll.
78+
`Results File Path` - Path to the xml file containing the tests results. If it's an existing file, RTF will replace it.
79+
`Working Directory` - Path to where the testing Revit files are.
80+
`Additional Resolution Directories` - Path to find Dynamo Core location when it is not set in the `Dynamo.Config` in DynamoRevit bin folder.
4681
`Debug` - Check this if you decide to launch a debug session.
82+
`Timeout` - in milliseconds, the maximum time for a test to run. If a test doesn't finish in this time, Revit will be forcefully terminated and new test session without the offending test will start (the offending test will be marked as `timedout`).
83+
`Continuous` - same as above, run tests without restarting Revit for each test.
84+
`GroupByModel` - same as above, run tests with the same model without reopening the model.
4785

4886
## Results
4987

50-
The output file from a test run is an nunit-formatted results file compatible with many CI systems.
88+
The output file from a test run is an nunit-formatted results file compatible with many CI systems.
89+
For documentation how to use RTF inside a CI system, see [this guide](docs/using_with_ci.md)
5190

5291
## Revit Versions
5392

5493
This repo maintains branches to track the two most recently released versions of Revit and one un-released version of Revit. When new versions of Revit are released, branches tracking the oldest version of Revit supported will no longer be maintained. For example, when Revit 2016 is released, the Revit 2014 branch of RTF will no longer be maintained.
55-
When testing, you should run the version of RTF corresponding to the version of Revit you are running. This will ensure that tests you have created, based on one Revit API, will correspond to the version of the API running on Revit.
94+
When testing, you should run the version of RTF corresponding to the version of Revit you are running. This will ensure that tests you have created, based on one Revit API, will correspond to the version of the API running on Revit.
95+
However, the current version of RTF works and can be used to test within Revit 2017, 2018, and 2019.
5696

5797
## License
5898

appveyor.yml.deleteme

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
version: 1.19.{build}
2+
pull_requests:
3+
do_not_increment_build_number: true
4+
branches:
5+
only:
6+
- mark/Revit2019
7+
skip_tags: true
8+
image: Visual Studio 2017
9+
configuration: Release
10+
assembly_info:
11+
patch: true
12+
file: '**\AssemblyInfo.*'
13+
assembly_version: '{version}'
14+
assembly_file_version: '{version}'
15+
assembly_informational_version: '{version}'
16+
before_build:
17+
- cmd: nuget restore .\src\
18+
build:
19+
project: .\src\RevitTestFramework.sln
20+
verbosity: minimal
21+
after_build:
22+
- cmd: nuget pack src\RevitTestFramework.nuspec -Version %APPVEYOR_BUILD_VERSION%
23+
test:
24+
assemblies:
25+
only:
26+
- .\bin\AnyCPU\Release\RunnerTests.dll
27+
artifacts:
28+
- path: RevitTestFramework*.nupkg
29+
name: nupkg
30+
deploy:
31+
- provider: NuGet
32+
api_key:
33+
secure: cN7zY+VTH8QH103SZn3xen5q3ZNqDvB4a5JKcYTGzBfnFRzCn/kldBPip6ENyCFF
34+
artifact: nupkg
35+
on:
36+
branch: mark/Revit2019

docs/using_with_ci.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Configuring CI to use RTF
2+
3+
This doc describes how to configure a CI system and use RevitTestFramework to run Revit tests on the CI machine.
4+
This document will describe setup for Microsoft Visual Studio and AWS EC2, however, the general instructions will work on other systems, e.g. Jenkins, TeamCity, etc.
5+
6+
1. **Setup Visual Studio Team Services**
7+
Visual Studio Team Services serves as a master in our CI. You can also use Jenkins for this purpose as well.
8+
You will need to host your own machine (steps below) for actually executing the build/test steps as that machine will have to have Revit installed (default VSTS machines, naturally, do not have it installed)
9+
1. Create an account if you don't have one yet
10+
1. Set up an agent pool (we have 2 pools one for general build/test and one for UI tests)
11+
1. Setup a new build pipeline:
12+
1. As an example, you can use one pipeline for build and one pipeline for UI tests
13+
1. Connect to your code repository (git/bitbucket/etc), this will popup oauth
14+
1. Specify an agent pool to run on
15+
An agent pool is a pool of machines that can service a paricular pipeline. Since, in this example, we have 2 pipelines, we will use the `Default` pool for one of them and create a new one, `UI Tests` for the Revit UI tests pipeline
16+
1. Define the pipeline
17+
These are steps that the build agent will perform to execute the tests, as an example, here are the steps for the pipeline we use:
18+
1. Get sources
19+
2. VsTest Platform Installer
20+
3. Build binaries (we use a PowerShell script to perform the build, but you can use the default MSBuild step)
21+
4. Run Revit UI Tests
22+
We use a PowerShell script here as well, which essentially executes our RTF tests, e.g.:
23+
```
24+
RevitTestFrameworkConsole.exe --dir .\bin\Release -a MyTest.dll -r .\MyTestResults.xml -revit:"C:\Program Files\Autodesk\Revit 2019\Revit.exe" --continuous
25+
```
26+
5. Publish Test Results
27+
This steps takes the XML file produced by RTF and publishes it so that VSTS understands which tests pass and which fail.
28+
Select *NUnit* for Test result format and your test result file, e.g. `.\MyTestResults.xml`
29+
1. At this point you can also configure triggers for each build pipeline (e.g. a pull request, or a merge into a specific branch, etc)
30+
31+
1. **Setup the build server**
32+
Now we setup a build machine that will connect to VSTS above and execute the build pipeline
33+
1. Decide where to host the build machine (AWS/Azure/local/etc) and what Windows variant you want to use. We use AWS and run our CI on Windows Server 2016.
34+
1. Spin up a new instance, I recommend at least 16GB of RAM and 4 processors with ~150gb of storage (`m5.xlarge` on AWS)
35+
*Security note:* Since you will need to remote into this machine, it needs to be open to the world. To mitigate security risks:
36+
* make sure you have a strong password (or use automatically generated AWS password)
37+
* limit the IPs that are allowed to access this machine to the IP of your office (you can use whatsmyip.org)
38+
1. Remote into your new instance (as `localhost\Administrator`)
39+
1. Create a new **non-admin** account (e.g. `vsagent`) on the machine (make sure it's a strong password and you have it saved somewhere safe!)
40+
1. Setup some convenience stuff
41+
* Create a PowerShell shortcut on the desktop
42+
* Create a shortcut on the desktop to launch CMD as `vsagent` user, e.g. a shortcut to:
43+
`C:\tools\PsExec.exe -accepteula -w c:\agent -i -u vsagent cmd.exe`
44+
This will allow you to run programs as `vsagent` user while being logged in as `Administrator`
45+
1. Download and install necessary software on the machine:
46+
*Note:* you will not be able to use IE on the remote machine (if it's Windows Server) because it is locked down. I don't recommend removing the lockdown or installing some other browsers - this machine should be secure!
47+
I recommend getting the link to each download on your personal computer, then pasting that link into a PowerShell on the remote, e.g.:
48+
```PowerShell
49+
# Disable progress bar: makes downloads ~50x faster
50+
$ProgressPreference = "SilentlyContinue"
51+
52+
# Download the file
53+
Invoke-WebRequest <PASTE URL> -OutFile <FileName>
54+
```
55+
1. [Git](https://git-scm.com/download/win) (or other source control software needed to connect to your source code repository, use defaults)
56+
1. [Visual Studio](https://www.visualstudio.com/downloads/), scroll down to [VS Build tools](https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=15)
57+
Make sure to select the following components to be installed (in addition to defaults):
58+
* .NET for desktop
59+
* Windows SDK (latest version)
60+
* Click-once tools
61+
1. [Wix](https://github.com/wixtoolset/wix3/releases/download/wix3111rtm/wix311.exe) or whatever other tool you need to build your installer/setup package.
62+
* If you use Wix, you will need to enable .NET 3.5 on the server, you can do this in the *Turn on Optional Features* control panel.
63+
You will probably need to reboot after this.
64+
* Install Wix
65+
* You will need to add the following system-wide environment variables:
66+
```
67+
WixCATargetsPath = "C:\Program Files (x86)\WiX Toolset v3.11\SDK\wix.ca.targets"
68+
WixTargetsPath = "C:\Program Files (x86)\MSBuild\Microsoft\WiX\v3.x\wix.targets"
69+
```
70+
1. [PsTools](https://docs.microsoft.com/en-us/sysinternals/downloads/pstools), simply extract the .zip into a folder, e.g. `c:\tools`
71+
1. VsAgent click the *Download Agent* button on your VSTS account webpage. To install it, just unzip it to a new folder: `c:\agent`
72+
1. Revit (we use 2019.1 for our CI)
73+
* Once installed, you will need to run the Revit once to register it and dismiss any first run prompts (e.g. EULA, etc). This will require allowing Autodesk registration site to bypass IE security settings:
74+
* Open an interactive session to the `vsagent` user with `psexec` (or the shortcut we created above):
75+
`C:\tools\PsExec.exe -i -u vsagent cmd.exe`
76+
* In the CMD for `vsagent`, open Internet Explorer:
77+
`c:\Program Files\Internet Explorer\iexplore.exe`
78+
* In IE, click on the gear/*Tools* icon, *Internet Options*, *Security*, *Trusted Sites*, *Sites*, and add `https://registeronce.autodesk.com` to the list.
79+
* Close IE
80+
* Now, from the same command window, run Revit, e.g.
81+
`C:\Program Files\Autodesk\Revit 2019\Revit.exe`
82+
* Accept all prompts, login, whatever you need to do, then close Revit.
83+
* For good measure, run Revit again and make sure no prompt show up - as they will cause issues with RTF
84+
1. At this point we have a machine that can run our CI/Revit UI tests, let's make a snapshot (AMI) of it so we can easily spin up as many of these as we want. For AWS/AMI:
85+
* (on the remote machine) Open `Ec2LaunchSettings`
86+
* Keep all settings, and click *Shutdown with Sysprep*
87+
* In the EC2 console, select the instance and chose *Image* -> *Create Image* from the *Actions* menu (give the image a descriptive name, e.g. `Revit Addin CI`)
88+
* This will take a few minutes. Once done you can use this AMI to spin up as many worker agents as you want.
89+
90+
1. Spin up a build server and connect it to Visual Studio Team Services
91+
1. If using an AMI, use that AMI. Optionally, you can skip the AMI step and use the machine instance from above directly (though it's not recommended)
92+
Settings to consider:
93+
* You can assign an AWS role to the machine such that it has credentials to access any private resources you may need (e.g. if you want to deploy data to an S3 bucket)
94+
* You can create a security group which limits remote connection to your IP addresses and assign that security group to the machine
95+
1. Once the machine is booted up, remote into it.
96+
For credentials, use `localhost\Administrator` and the password you decrypt on AWS console (with the PEM file)
97+
1. You may want to consider installing code signing certificate at this point if you are signing your Revit Addin (highly recommended)
98+
1. Open CMD to `vsagent` (see steps above)
99+
1. Open `certmgr` from CMD
100+
1. Install the certificate into personal store
101+
1. Finally, configure the Visual Studio agent, open a PowerShell window and:
102+
```PowerShell
103+
cd c:\agent
104+
.\config.cmd
105+
106+
# Follow the prompts
107+
# Server url: your VSTS url, e.g. https://[mybuild].visualstudio.com
108+
# Auth type: PAT
109+
# PAT: (get it from https://[mybuild].visualstudio.com/_usersSettings/tokens)
110+
# Pool: use default for CI and UI Tests for Revit (or whatever pools you created above)
111+
# Agent name: e.g. REVIT-CI-1
112+
# Work folder: [default value]
113+
# Run as service: NO
114+
# Configure autologon: YES
115+
# Account to use: vsagent [+ your password when prompted]
116+
```
117+
Reboot.
118+
1. Once rebooted you should see your new agent on Visual Studio Team Services webpage
119+
1. Queue up a new build and see if it works!
120+
121+
1. Debugging when things go wrong...
122+
In some cases, you just need to remote into the build machine to debug a broken build.
123+
Since the build runs as the `vsagent` account but `vsagent` account can remote into the machine, you will have to follow these steps:
124+
1. Open AWS console, EC2 instances
125+
2. Select the instance and click *Connect*
126+
3. Use the PEM file to decrypt the password
127+
4. Once connected (you will always connect with `localhost\Administrator` account), open *Task Manager* and click on *Users* then right click on `vsagent` and click connect.
128+
5. Now you can run and debug on the live machine

images/RTF_UI.PNG

-21.1 KB
Loading

0 commit comments

Comments
 (0)