8 Coding Guidelines - essenius/FitNesseRun GitHub Wiki
FitNesseRun
was written in Powershell and uses Pester 4 as the unit testing framework. For the transformation of the FitNesse raw output to NUnit and HTML, XSLT is used.
PowerShell conventions
Follow the standard PowerShell coding conventions, including use of verbs (check with Script Analyzer). Functions with scope beyond the current script use a dash between the verb and the rest of the name, internal functions don't. This convention is especially useful for modules as it allows for exporting everything with a dash in it. Capitalize function parameters, and use camelCase for local variables (even though PowerShell is not case sensitive).
New functionality will only be made available for the development version. The stable version will only receive high severity bug fixes.
To allow for high code coverage, as much functionality as possible is put in functions, and leave the main code as small as possible. It's a matter of identifying whether the code is run by Pester, and calling a function InvokeMainTask
if not. This means that this InvokeMainTask
call is the only statement that cannot be covered by Pester.
Create functions for everything that you might want to mock during unit testing. That includes things like executing external code, or interaction with the file system or operating system. Make code self-describing as much as possible; favor clarity above cleverness and create functions that show their intent if it's not directly clear from the code, even if there is very little code in them. Functions should also not be larger than 30 lines and should not have a cyclomatic complexity of higher than 10.
XSLT Conventions
Make sure that all XSLT code is covered as well in Pester test cases. The test cases are recorded in xslTests.xml. Every test case contains the expected raw FitNesse input in <fitnesseInput>
elements. Expected NUnit 3 output is captured in <expectedNUnit3Output>
elements, and expected HTML output in <expectedDetails>
.
Preparing for pull requests
In the main folder you will see the file PesterAndPackage.ps1
. This takes care of running all unit tests for the development version and can also create a package if all unit tests pass and code coverage thresholds have passed. To prepare for pull requests, run this script with the -noPackage
option and ensure it finishes successfully.
The extension author can upload a new version to the Marketplace, and will also use PesterAndPackage to create the VSIX package needed for the upload to Market Place. Only pull requests that pass visual inspection and static analysis, pass all tests and meet code coverage thresholds will be approved.
Folder Structure
The FitNesseRun
and FitNesseConfigure
tasks each have their own folder in the source tree. In the folder, there are subfolders for each version, named after the task with a version appended to it (e.g. FitNesseRunV0
). The task.json
file will have a corresponding main version.
There is also a Common
folder with modules that are used by both tasks. Azure DevOps tasks cannot look outside their own folder structure so need to contain all code, but I am also a believer in DRY (don't repeat yourself). Therefore I did not want to copy these over to each version of each task. The deployment (see vss-extension.json
) will take care of copying over the contents of the Common
folder to the task. This required the tasks to be aware whether they are run locally or on an agent. During local development, the tasks will use the versions in the source folder directly, and on the agent they will be assumed to be in the task folder. The content of Common
has been very stable, so I have not seen the need yet to give that folder main versions too.