Merge pull request #752 from PowerShell/docs

Documentation refactor
This commit is contained in:
Andy Schwartzmeyer
2016-03-30 23:41:59 -07:00
25 changed files with 888 additions and 746 deletions
+20 -21
View File
@@ -1,23 +1,22 @@
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch",
"type": "coreclr",
"request": "launch",
"justMyCode": false,
"stopAtEntry": true,
"program": "${workspaceRoot}/bin/powershell",
"args": [ ],
"preLaunchTask": "build",
"cwd": "${workspaceRoot}"
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"justMyCode": false,
"processName": "powershell"
}
]
"configurations": [
{
"name": ".NET Core Launch",
"type": "coreclr",
"request": "launch",
"justMyCode": false,
"stopAtEntry": true,
"program": "${workspaceRoot}/bin/powershell",
"args": [ ],
"preLaunchTask": "build",
"cwd": "${workspaceRoot}"
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"justMyCode": false,
"processName": "powershell"
}
]
}
+12 -13
View File
@@ -1,16 +1,15 @@
{
"version": "0.1.0",
"command": "powershell",
"isShellCommand": true,
"showOutput": "verbose",
"args": [ "--command" ],
"command": "powershell",
"isShellCommand": true,
"showOutput": "verbose",
"args": [ "-c" ],
"tasks": [
{
"taskName": "build",
"args": [ "Import-Module ${workspaceRoot}/PowerShellGitHubDev.psm1; Start-PSBuild" ],
"isBuildCommand": true,
"problemMatcher": "$msCompile"
}
]
"tasks": [
{
"taskName": "build",
"args": [ "Import-Module ${workspaceRoot}/PowerShellGitHubDev.psm1; Start-PSBuild" ],
"isBuildCommand": true,
"problemMatcher": "$msCompile"
}
]
}
+42 -34
View File
@@ -1,6 +1,8 @@
# Contributing to Project Magrathea
Contributing to Project Magrathea
=================================
## Rules
Rules
-----
**Do not commit code changes to the master branch!**
@@ -22,15 +24,18 @@ Write *good* commit messages. Follow Tim Pope's [guidelines][]:
* The rest should be a wrapped, detailed explanation of the what and why
* The tone should be imperative
[submodules]: https://www.git-scm.com/book/en/v2/Git-Tools-Submodules
[guidelines]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
## New to Git?
New to Git?
-----------
- [Git 101](docs/git-101.md) : install and getting started.
- [Git for sd users](docs/git-sd.md) : a handy reference document for people familiar with `sd`.
- [Commit process](docs/git-commit.md) : step-by-step commit guide with all gory details.
- [Git Basics](docs/git/basics.md): install and getting started.
- [Git for sd users](docs/git/source-depot.md): a handy reference document for people familiar with `sd`.
- [Commit process](docs/git/committing.md): step-by-step commit guide with all gory details.
#### Authentication
Authentication
--------------
If you do not have a preferred method of authentication, enable the storage
credential helper, which will cache your credentials in plaintext on your
@@ -43,33 +48,33 @@ git config --global credential.helper store
Alternatively, on Windows, you can try the
[Git Credential Manager for Windows][manager].
[manager]: https://github.com/Microsoft/Git-Credential-Manager-for-Windows
[Git for Windows]: https://git-scm.com/download/win
[token]: https://help.github.com/articles/creating-an-access-token-for-command-line-use/
[submodules]: https://www.git-scm.com/book/en/v2/Git-Tools-Submodules
[manager]: https://github.com/Microsoft/Git-Credential-Manager-for-Windows
## Microsoft employees
Microsoft employees
-------------------
Microsoft employees should follow Microsoft open source [guidelinces][MS-OSS-Hub].
Particularly:
* [Join][MS-OSS-Hub] Microsoft github organization.
* [Join][MS-OSS-Hub] Microsoft GitHub organization.
* Use your `alias@microsoft.com` for commit messages email.
It the requirement for contributions made as part of your work at Microsoft.
* Enable [2 factor authentication][].
[MS-OSS-Hub]: https://opensourcehub.microsoft.com/articles/how-to-join-microsoft-github-org-self-service
[2 factor authentication]: https://github.com/blog/1614-two-factor-authentication
## Branches
Branches
--------
* Checkout a new local branch for every change you want to make (bugfix, feature).
* Use `alias/feature-name` pattern.
* Use lowercase-with-dashes for naming.
* Use same branch name in super-project and all [submodules](#submodules).
* Use same branch name in super-project and all [submodules][].
## Permissions
Permissions
-----------
If you have difficulty in pushing your changes, there is a high
probability that you actually don't have permissions.
@@ -82,30 +87,33 @@ repositories, as you can also just [fork a repo][].
[fork a repo]: https://help.github.com/articles/fork-a-repo/
## Rebase and Fast-Forward Merge Pull Requests
Rebase and Fast-Forward Merge Pull Requests in Submodules
---------------------------------------------------------
Because GitHub's "Merge Pull Request" button merges with `--no-ff`, an extra
merge commit will always be created. This can be especially annoying when
trying to commit updates to submodules. Therefore our policy is to merge using
the Git CLI after approval, with a rebase onto master to enable a fast-forward
merge. If you are uncomfortable doing this, please ask @andschwa to merge.
*This is not necessary in the superproject, only submodules!*
## Submodules
Because GitHub's "Merge Pull Request" button merges with `--no-ff`, an
extra merge commit will always be created. This can be especially
annoying when trying to commit updates to submodules. Therefore our
policy is to merge using the Git CLI after approval, with a rebase
onto master to enable a fast-forward merge.
This repository is a superproject with a half-dozen [submodules][]. **DO NOT**
commit updates unless absolutely necessary. When submodules must be updated, a
separate Pull Request must be submitted, reviewed, and merged before updating
the superproject. When committing submodule updates, ensure no other changes
are in the same commit. Submodule bumps may be included in feature branches for
ease of work, but the update must be independently approved before merging into
master.
Submodules
----------
[submodules]: https://www.git-scm.com/book/en/v2/Git-Tools-Submodules
This repository is a superproject with a half-dozen [submodules][].
**DO NOT** commit updates unless absolutely necessary. When submodules
must be updated, a separate Pull Request must be submitted, reviewed,
and merged before updating the superproject. When committing submodule
updates, ensure no other changes are in the same commit. Submodule
bumps may be included in feature branches for ease of work, but the
update must be independently approved before merging into master.
## Recommended Git configurations
Recommended Git configurations
------------------------------
I highly recommend these configurations to help deal with whitespace, rebasing,
and general use of Git.
We highly recommend these configurations to help deal with whitespace,
rebasing, and general use of Git.
> Auto-corrects your command when it's sure (`stats` to `status`)
```sh
+54 -408
View File
@@ -1,12 +1,57 @@
# PowerShell on Linux / OS X / Windows
PowerShell
==========
| |Ubuntu 14.04 |Windows |
|---------|:------:|:------:|
|master|[![Build Status](https://travis-ci.com/PowerShell/PowerShell.svg?token=31YifM4jfyVpBmEGitCm&branch=master)](https://travis-ci.com/PowerShell/PowerShell)|[![Build status](https://ci.appveyor.com/api/projects/status/wb0a0apbn4aiccp1/branch/master?svg=true)](https://ci.appveyor.com/project/PowerShell/powershell-linux/branch/master)|
This repository is "Project Magrathea": Open PowerShell on GitHub, for
Linux, Windows (.NET Core and Full), and OS X. It is built using the
[.NET Command Line Interface][dotnet-cli] to support targetting every
flavor of PowerShell. It is a collaborative effort among many teams:
## [Waffle.io scrum board](https://waffle.io/PowerShell/PowerShell)
- Full PowerShell
- Core PowerShell
- Open Source Technology Center
- .NET Foundation
## Obtain the source code
[dotnet-cli]: https://github.com/dotnet/cli
Build Status
------------
| Platform | `master` |
|--------------|----------|
| Ubuntu 14.04 | [![Build Status](https://travis-ci.com/PowerShell/PowerShell.svg?token=31YifM4jfyVpBmEGitCm&branch=master)](https://travis-ci.com/PowerShell/PowerShell) |
| Windows | [![Build status](https://ci.appveyor.com/api/projects/status/wb0a0apbn4aiccp1/branch/master?svg=true)](https://ci.appveyor.com/project/PowerShell/powershell-linux/branch/master) |
Get PowerShell
--------------
| | Linux | Windows .NET Core | Windows .NET Full | OS X | PSRP |
|-----------------------|-------|-------------------|-------------------|------|------|
| Build from **Source** | [Instructions](docs/building/linux.md) | [Instructions](docs/building/windows-core.md) | [Instructions](docs/building/windows-full.md) | [Instructions](docs/building/osx.md) | [Instructions](docs/building/psrp.md) |
| Get **Binaries** | [Releases][] | [Artifacts][] | [Artifacts][] | [Releases][] | TBD |
Building summary: `Start-PSBuild` from the module
`./PowerShellGitHubDev.psm1` (self-host on Linux / OS X)
See [Linux releases](docs/installation/linux.md) and
[Windows artifacts](docs/installation/windows.md) installation
instructions.
[releases]: https://github.com/PowerShell/PowerShell/releases
[artifacts]: https://ci.appveyor.com/project/PowerShell/powershell-linux/build/artifacts
Team coordination
-----------------
- [PSCore Slack chat](https://pscore.slack.com/)
- [Waffle.io scrum board](https://waffle.io/PowerShell/PowerShell)
If you encounter any problems, see the [known issues](KNOWNISSUES.md),
search the [issues][], and if all else fails, open a new issue.
[issues]: https://github.com/PowerShell/PowerShell/issues
Obtain the source code
----------------------
### Setup Git
@@ -22,405 +67,6 @@ rules, and Git best practices.
Clone this repository. It is a "superproject" and has a number of
other repositories embedded within it as submodules. *Please* see the
contributing guidelines and learn about submodules.
```sh
git clone https://github.com/PowerShell/PowerShell.git
cd PowerShell
```
#### Linux
Linux will need every submodule, so update them recursively:
```sh
git submodule update --init --recursive
```
The `src/omi` submodule requires your GitHub user to have joined the Microsoft
organization. If it fails to check out, Git will bail and not check out further
submodules either. Please follow the instructions on the [Open Source Hub][].
[Open Source Hub]: https://opensourcehub.microsoft.com/articles/how-to-join-microsoft-github-org-self-service
#### Windows
On Windows, many fewer submodules are needed, so specify them:
```sh
git submodule update --init --recursive -- src/windows-build src/Microsoft.PowerShell.Linux.Host/Modules/Pester
```
## Setup build environment
We use the [.NET Command Line Interface][dotnet-cli] (`dotnet`) to
build the managed components, and [CMake][] to build the native
components (on non-Windows platforms). Install `dotnet` by following
their [documentation][cli-docs].
The version of .NET CLI is very important, you want a recent 1.0.0 beta
(**not** 1.0.1). The following instructions will install precisely
1.0.0.001888, though any 1.0.0 version *should* work.
> Previous installations of DNX, `dnvm`, or older installations of .NET CLI
> can cause odd failures when running. Please check your version.
[dotnet-cli]: https://github.com/dotnet/cli#new-to-net-cli
[cli-docs]: https://dotnet.github.io/getting-started/
[CMake]: https://cmake.org/cmake/help/v2.8.12/cmake.html
### Linux
Tested on Ubuntu 14.04.
This installs the .NET CLI package feed. The benefit to this is that
installing `dotnet` using `apt-get` will also install all of its
dependencies automatically.
```sh
sudo sh -c 'echo "deb [arch=amd64] http://apt-mo.trafficmanager.net/repos/dotnet/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list'
sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
sudo apt-get update
sudo apt-get install dotnet=1.0.0.001675-1
```
The drawback of using the feed is that it gets out of date. The pinned
version is the most recent package published to the feed, but newer
packages are available. To upgrade the package, install it by
hand. Unfortunately, `dpkg` does not handle dependency resolution, so
it is recommended to first install the older version from the feed,
and then upgrade it.
```sh
wget https://dotnetcli.blob.core.windows.net/dotnet/beta/Installers/Latest/dotnet-ubuntu-x64.latest.deb
sudo dpkg -i ./dotnet-ubuntu-x64.latest.deb
```
Additionally, PowerShell on Linux builds a native library, so install
the following additional build / debug tools.
```sh
sudo apt-get install g++ cmake make lldb-3.6 strace
```
### Windows
Tested on Windows 10 and Windows Server 2012 R2.
```powershell
Invoke-WebRequest -Uri https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/install.ps1 -OutFile install.ps1
./install.ps1 -version 1.0.0.001888
$env:Path += ";$env:LocalAppData\Microsoft\dotnet\cli
```
If you meet `Unable to cast COM object of type 'System.__ComObject' to
interface type 'Microsoft.Cci.ISymUnmanagedWriter5'`, please install
[Visual C++ Redistributable for Visual Studio 2015][redist].
[redist]: https://www.microsoft.com/en-hk/download/details.aspx?id=48145
### OS X
The OS X dependency installation instructions are not yet documented. You can
try their PKG installer, or their [obtain script][]. We do not (yet) routinely
test on OS X, but some developers use PowerShell on 10.10 and 10.11.
[obtain script]: https://github.com/dotnet/cli/blob/rel/1.0.0/scripts/obtain/install.sh
## Building
**The command `dotnet restore` must be done at least once from the top directory
to obtain all the necessary .NET packages.**
Build with `./build.sh` on Linux and OS X.
`Start-PSBuild` from module `./PowerShellGitHubDev.psm1` on Windows
and Linux / OS X, if you are self-hosting PowerShell.
Specifically:
### Linux
In Bash:
```sh
cd PowerShell
dotnet restore
./build.sh
```
### Windows
In PowerShell:
```powershell
cd PowerShell
dotnet restore
Import-Module .\PowerShellGitHubDev.psm1
Start-PSBuild # build CoreCLR version
Start-PSBuild -FullCLR # build FullCLR version
```
**Tip:** use `Start-PSBuild -Verbose` switch to see more information
about build process.
## Running
If you encounter any problems, see the [known issues](KNOWNISSUES.md),
otherwise open a new issue on GitHub.
The local managed host has built-in documentation via `--help`.
### Linux / OS X
- launch local shell with `./bin/powershell`
- run tests with `./pester.sh`
### Windows
- launch `./bin/powershell.exe`
- run tests with `./bin/powershell.exe -c "Invoke-Pester test/powershell"`
## Debugging
To enable debugging on Linux, follow the installation instructions for
[Experimental .NET Core Debugging in VS Code][VS Code]. You will also
want to review their [detailed instructions][vscclrdebugger].
VS Code will place a `.vscode` directory in the PowerShell folder.
This contains the `launch.json` file, which you will customize using
the instructions below. You will also be prompted to create a
`tasks.json` file.
Currently, debugging supports attaching to a currently running
powershell process. Assuming you've created a `launch.json` file
correctly, within the "configuration" section, use the below settings:
```json
"configurations": [
{
"name": "powershell",
"type": "coreclr",
"request": "attach",
"processName": "powershell"
}
]
```
VS Code will now attach to a running `powershell` process. Start
powershell, then (in VS Code) press `F5` to begin the debugger.
[VS Code]: https://blogs.msdn.microsoft.com/visualstudioalm/2016/03/10/experimental-net-core-debugging-in-vs-code/
[vscclrdebugger]: http://aka.ms/vscclrdebugger
## PowerShell Remoting Protocol
PSRP communication is tunneled through OMI using the `omi-provider`.
> PSRP has been observed working on OS X, but the changes made to OMI to
> accomplish this are not even beta-ready and need to be done correctly. They
> exist on the `andschwa-osx` branch of the OMI repository.
PSRP support is *not* built automatically. See the detailed notes on
how to enable it.
### Running
Some initial setup on Windows is required. Open an administrative command
prompt and execute the following:
```cmd
winrm set winrm/config/Client @{AllowUnencrypted="true"}
winrm set winrm/config/Client @{TrustedHosts="*"}
```
> You can also set the `TrustedHosts` to include the target's IP address.
Then on Linux, launch `omiserver` in the debugger (after building with the
instructions above):
```sh
./psrp.sh
run
```
> The `run` command is executed inside of LLDB (the debugger) to start the
`omiserver` process.
Now in a PowerShell prompt on Windows (opened after setting the WinRM client
configurations):
```powershell
Enter-PSSession -ComputerName <IP address of Linux machine> -Credential $cred -Authentication basic
```
> The `$cred` variable can be empty; a credentials prompt will appear, enter
> any fake credentials you wish as authentication is not yet implemented.
The IP address of the Linux machine can be obtained with:
```sh
ip -f inet addr show dev eth0
```
## Detailed Build Script Notes
> This sections explains the build scripts.
The variable `$BIN` is the output directory, `bin`.
### Managed
Builds with `dotnet`. Publishes all dependencies into the `bin` directory.
Emits its own native host as `bin/powershell`. Uses a `Linux` configuration to
add a preprocessor definition. The `CORECLR` definition is added only when
targeting the `netstandard1.5` framework. The `LINUX` definition is added only
when `--configuration Linux` is used.
```sh
cd src/Microsoft.PowerShell.Linux.Host
dotnet publish --configuration Linux
```
### Native
The `libpsl-native.so` library consists of native functions that
`CorePsPlatform.cs` P/Invokes.
#### libpsl-native
Driven by CMake, with its own unit tests using Google Test.
```sh
cd src/libpsl-native
cmake -DCMAKE_BUILD_TYPE=Debug .
make -j
ctest -V
# Deploy development copy of libpsl-native
cp native/libpsl-native.* $BIN
```
The output is a `.so` on Linux and `.dylib` on OS X. It is unnecessary for Windows.
### PSRP
#### OMI
**PSRP support is not built by `./build.sh`**
To develop on the PowerShell Remoting Protocol (PSRP) for Linux, you'll need to
be able to compile OMI, which additionally requires:
```sh
sudo apt-get install libpam0g-dev libssl-dev libcurl4-openssl-dev libboost-filesystem-dev
```
Note that the OMI build steps can be done with `./omibuild.sh`.
Build OMI from source in developer mode:
```sh
cd src/omi/Unix
./configure --dev
make -j
```
#### Provider
The provider uses CMake to build, link, and register with OMI.
```sh
cd src/omi-provider
cmake .
make -j
```
The provider also maintains its own native host library to initialize the CLR,
but there are plans to refactor .NET's packaged host as a shared library.
### FullCLR PowerShell
On Windows, we also build Full PowerShell for .NET 4.5.1
#### Setup environment
* Install the Visual C++ Compiler via Visual Studio 2015.
This component is required to compile the native `powershell.exe` host.
This is an optionally installed component, so you may need to run the
Visual Studio installer again.
If you don't have any Visual Studio installed, you can use
[Visual Studio 2015 Community Edition][vs].
> Compiling with older versions should work, but we don't test it.
**Troubleshooting note:** If `cmake` says that it cannot determine the
`C` and `CXX` compilers, you either don't have Visual Studio, or you
don't have the Visual C++ Compiler component installed.
* Install CMake and add it to `PATH.`
You can install it from [Chocolatey][] or [manually][].
```
choco install cmake.portable
```
* Install .NET CLI via their [documentation][cli-docs]
[vs]: https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx
[Chocolatey]: https://chocolatey.org/packages/cmake.portable
[manually]: https://cmake.org/download/
#### Building
```powershell
Start-PSBuild -FullCLR
```
**Troubleshooting:** the build logic is relatively simple and contains following steps:
- building managed DLLs: `dotnet publish --runtime net451`
- generating Visual Studio project: `cmake -G "$cmakeGenerator"`
- building `powershell.exe` from generated solution: `msbuild powershell.sln`
All this steps can be run separately from `Start-PSBuild`, don't
hesitate to experiment.
## Running
Running FullCLR version is not as simple as CoreCLR version.
If you just run ~~`.\binFull\powershell.exe`~~, you will get a `powershell`
process, but all the interesting DLLs (i.e. `System.Management.Automation.dll`)
would be loaded from the GAC, not your `binFull` build directory.
[@lzybkr](https://github.com/lzybkr) wrote a module to deal with it and run
side-by-side.
```powershell
Import-Module .\PowerShellGithubDev.psm1
Start-DevPSGithub -binDir $pwd\binFull
```
**Troubleshooting:** default for `powershell.exe` that **we build** is x86.
There is a separate execution policy registry key for x86, and it's likely that
you didn't ~~bypass~~ enable it. From **powershell.exe (x86)** run:
```
Set-ExecutionPolicy Bypass
```
## Running from CI server
We publish an archive with FullCLR bits on every CI build with [AppVeyor][].
* Download zip package from **artifacts** tab of the particular build.
* Unblock zip file: right-click in file explorer -> properties -> check
'Unblock' checkbox -> apply
* Extract zip file to `$bin` directory
* `Start-DevPSGithub -binDir $bin`
[appveyor]: https://ci.appveyor.com/project/PowerShell/powershell-linux
contributing guidelines and learn about submodules. Not every
submodule is required on every system; see the individual build
instructions for the necessary subsets.
-52
View File
@@ -1,52 +0,0 @@
# Ubuntu 14.04
Note that some of these dependencies are only required for building
CoreCLR and CoreFX on Linux. We should find a reduced set for
PowerShell on Linux itself.
Note that the distributed version of Mono is too old for .NET
projects, the [CoreCLR][] docs point to the [Mono][] docs on how to
install an up-to-date version.
Also note that the distributed version of Git has a bug with `git
clean -fdx` and submodules. I would recommned upgrading.
[CoreCLR]: https://github.com/dotnet/coreclr/blob/master/Documentation/building/linux-instructions.md
[Mono]: http://www.mono-project.com/docs/getting-started/install/linux/
```sh
sudo su
echo "Adding Mono Project repository"
echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
apt-get update
apt-get install -y \
git \
wget \
mono-devel \
gcc \
g++ \
llvm-3.5 \
clang-3.5 \
lldb-3.6 lldb-3.6-dev \
strace \
libicu-dev \
libunwind8 libunwind8-dev \
libssl-dev \
libcurl4-openssl-dev \
libpam0g-dev \
make \
cmake \
gettext
```
# Arch Linux
It's Arch, everything is already new enough.
```
sudo pacman --noconfirm -S git wget gcc mono make cmake icu pam lldb strace
```
-9
View File
@@ -1,9 +0,0 @@
# Native Code Testing Guide
"Native" tests are tests which validate the native C/C++ function calls into the system library. To run ONLY the native tests, it is assumed that you have completed the process in the README.md, and have run `source monad-docker.sh`.
From the scripts directory, run `monad-run make -j native-tests`. This will output an xml file to your scripts directory.
# Creating new tests
monad-linux/src/monad-native/src/tests is the test folder containing all the .cpp files. you will need to `#include <gtest/gtest.h>` and follow gtest guidelines for creating your test suite.
-116
View File
@@ -1,116 +0,0 @@
#Pester Testing Test Guide
## Who this is for
Cmdlet behavior is validated using the Pester testing framework. The purpose of this document is to create a single standard to maximize unit test coverage while minimizing confusion on expectations. What follows is a working document intended to guide those writing Pester unit tests for PSL.
Unit testing is done not only to validate that the block of code works as expected, but also to assist the developer to know precisely where in the code to look; in some cases, seeing the source code may inspire better unit tests. In many cases, a unit test *is* the only documented specification. Fortunately, the MSDN is a great source of information about Cmdlets.
Test suites need to be created and many cmdlets added and unit-tested. The following list is to be used to guide the thought process of the developer in writing a suite in minimal time, while enhancing quality.
Test suites should proceed as functional and system tests of the cmdlets, and the code treated as a black box for the purpose of test suite design.
### Use of Mocks
It is often necessary for the code to interact with the system or other components. When possible, use Mock objects to facilitate this in order to minimize external dependencies. Note: creating a Mock in PSL causes PowerShell to look at the Mock, never actually hitting any C# code. Cmdlets cannot be tested using Mocks.
### Aliases
Each cmdlet with an alias must be tested with all of its aliases at least once to verify the code path calls the original function.
## Testing Standards
### Readability
Every effort should be made to maximize readability of code. Code is written for the developer in the future to debug- not for the developer writing the code.
1) When assertions are on consecutive lines, the pipes should line up:
```sh
MyFirstCondition | Should Be 0
MySecondCondition | Should Be 1
```
This is less readable than:
```sh
MyFirstCondition | Should Be 0
MySecondCondition | Should Be 1
```
So the second section of code should instead be used. The same style should be followed for assignments of variables on consecutive lines:
```sh
$var1 = <expression 1>
$variable2 = <expression 2>
$var3 = <expression 3>
$typeCollection1 = <expression 4>
$object1 = <expression>
... etc
```
is much less readable than
```sh
$var1 = <expression 1>
$variable2 = <expression 2>
$var3 = <expression 3>
$typeCollection1 = <expression 4>
$object1 = <expression 5>
... etc
```
So all assignment statements must be aligned.
Other style standards are no less important to readability of the code:
2) Use readable and meaningful variable name when assigning variables.
3) Do not make large functions. Tests should be simple: define -> manipulate -> assert
4) Do not use tabs. Tabs are rendered differently depending upon the machine. This greatly affects readability.
5) Remove the first 3 auto-generated lines of each .Tests.ps1 file. This is created automatically by Pester and is unnecessary. Each .Test.ps1 file should begin with a Describe block.
6) Discard the auto-generated function file that is generated in tandem with the .Tests.ps1 file
7) Name the test file "Test-<cmdlet name > when you create a new test fixture.
8) Each test describes a behavior- use the word "Should" at the beginning of each test description- so it reads "It 'Should..."
### Basic Unit Tests
The following table should suffice to inspire in the developer sufficient content to create a suite of tests.
test # | test name | entry criteria/setup | exit criteria/assertion
-------|-----------|----------------------|------------------------
01 | Should be able to be called | without params (if applicable) | no throw
02 | Should be able to be called | minimal required params | no throw, expected output
03 | Should be able to use the X alias | minimal required params | no throw, expected output
04 | Should return the proper data type | required params | no throw, proper data type
05 | Should be able to accept piped input | piped input | expected output
06 | Should be able to call using the X parameter | use X parameter | no throw, expected output
07 | Should be able to call using the Y parameter | use Y parameter | no throw, expected output
08 | Should be able to call using the Z parameter | use Z parameter | no throw, expected output
09 | Should throw under condition X | create condition X | Throw error x
10 | Should throw under condition Y | create condition Y | Throw error y
11 | Should throw under condition Z | create condition Z | Throw error z
These are the **basic** unit tests required to verify the functionality of any Cmdlet. If the above questions cannot be answered for each Cmdlet, then they cannot be verified to work.
Look at the existing suites of pester tests located within `monad-linux/src/pester-test/` and use that as inspiration.
##Running Pester Tests
Pester tests may be run from outside of PowerShell via the command line. Build PowerShell and Pester using (assuming you're in the build folder) `./build.sh make ../src/pester-test/<filename>` or `./build.sh make pester-tests`
-34
View File
@@ -1,34 +0,0 @@
# PowerShell for Linux
This readme is targeted at PowerShell for Linux users looking to write test suites to ensure quality of PowerShell products.
## Getting started
These instructions assume Ubuntu 14.04 LTS. It is assumed that PowerShell for Linux is currently installed on the system.
### Obtain PowerShell
PowerShell is required to enable and run the test suites.
### Testing technology
Technology | Purpose
-------|------
Pester | default cmdlet test framework
xUnit | default C# test framework
cppUnit | default C/C++ testing framework
### Running the test suite
Tests can be run from the `scripts` folder. If you are currently in `monad-linux/scripts`, then run `./build.sh make test` to run the complete tests suite. The table below shows the commands to run for the various test products bundled with Powershell for Linux (the table assumes the current working directory is `monad-linux/scripts`).
It is strongly recommended that before major changes are tested, that users run `./build.sh make clean cleanall prepare` to ensure the environment is completely clean.
Technology | Run Method
------|---------
Pester | ./build.sh make pester-tests
xUnit | ./build.sh make xunit-tests
cppunit | ./build.sh make native-tests
hashbang tests | ./build.sh make hashbang-tests
within the `scripts` directory, you may also wish to run Pester tests on a single file. This can be done easily using `./build.sh make {path/from/scripts/to/pester/test}` (E.g, `./build.sh make ../src/pester-test/Test-TESTFILE.Test.ps1`).
+166
View File
@@ -0,0 +1,166 @@
Build PowerShell on Linux
=========================
This guide will walk you through building PowerShell on Linux. We'll
start by showing how to set up your environment from scratch.
Environment
===========
These instructions are written assuming the Ubuntu 14.04 LTS, since
that's the distro the team uses.
Toolchain Setup
---------------
We use the [.NET Command Line Interface][dotnet-cli] (`dotnet`) to
build the managed components, and [CMake][] to build the native
components. Install the following packages for the toolchain:
- `dotnet`
- `cmake`
- `make`
- `g++`
- `libunwind8`
- `libicu52`
And for debgging:
- `strace`
- `lldb-3.6`
In order to get `dotnet`, we need to add an additional package source:
```sh
sudo sh -c 'echo "deb [arch=amd64] http://apt-mo.trafficmanager.net/repos/dotnet/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list'
sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
sudo apt-get update
```
Then install the packages you need:
```sh
sudo apt-get install dotnet cmake make g++ libunwind8 libicu52 strace lldb-3.6
```
[dotnet-cli]: https://github.com/dotnet/cli#new-to-net-cli
[CMake]: https://cmake.org/cmake/help/v2.8.12/cmake.html
.NET CLI
--------
If you have any problems installing `dotnet`, please see their
[documentation][cli-docs].
The version of .NET CLI is very important, you want a recent build of
1.0.0 (**not** 1.0.1).
Previous installations of DNX, `dnvm`, or older installations of .NET
CLI can cause odd failures when running. Please check your version.
The drawback of using the feed is that it gets out of date. To upgrade
the package, install it by hand. Unfortunately, `dpkg` does not handle
dependency resolution, so it is recommended to first install the older
version from the feed, and then upgrade it.
```sh
wget https://dotnetcli.blob.core.windows.net/dotnet/beta/Installers/Latest/dotnet-ubuntu-x64.latest.deb
sudo dpkg -i ./dotnet-ubuntu-x64.latest.deb
```
[cli-docs]: https://dotnet.github.io/getting-started/
Git Setup
---------
Please clone the superproject (this repo) and initialize a subset of
the submodules:
```sh
git clone https://github.com/PowerShell/PowerShell.git
cd PowerShell
git submodule update --init --recursive -- src/windows-build src/libpsl-native src/Microsoft.PowerShell.Linux.Host/Modules/Pester
```
Build using our module
======================
We maintain a `PowerShellGitHubDev.psm1` PowerShell module with the
function `Start-PSBuild` to build PowerShell. Since this is PowerShell
code, it requires self-hosting. Fortunately, this is as easy as
downloading and installing the package. Unfortunately, while the
repository is still private, the package cannot be downloaded as
simply as with `wget`. We have a script that wraps the GitHub API and
uses a personal access token to authorize and obtain the package.
> You can alternativelly download via a browser and upload it to your
> box via some other method
```sh
GITHUB_TOKEN=<replace with your token> ./download.sh
sudo dpkg -i ./powershell.deb
powershell
```
You should now be in a `powershell` console host that is installed
separately from any development copy you're about to build. Just
import our module and build!
```powershell
Import-Module ./PowerShellGitHubDev.psm1
Start-PSBuild
```
Congratulations! If everything went right, PowerShell is now built and
executable as `./bin/powershell`.
> Note that the `./build.sh` script is deprecated and may be removed
You can run our cross-platform Pester tests with `./bin/powershell -c
"Invoke-Pester test/powershell"`.
Build manually
==============
The following goes into detail about what `Start-PSBuild` does.
Build the native library
------------------------
The `libpsl-native.so` library consists of native functions that
`CorePsPlatform.cs` P/Invokes.
```sh
pushd src/libpsl-native
cmake -DCMAKE_BUILD_TYPE=Debug .
make -j
make test
popd
```
This library will be emitted in the
`src/Microsoft.PowerShell.Linux.Host` project, where `dotnet` consumes
it as "content" and thus automatically deploys it.
Build the managed projects
--------------------------
The `Linux.Host`, while poorly named, is the cross-platform host for
PowerShell targetting .NET Core. It is the top level project, so
`dotnet publish` transitively builds all its dependencies, and emits a
`powershell` executable and all necessary libraries (both native and
managed) in a flat directory (specified with `--output`, otherwise
automatically nested depending on runtime, configuration, and
framework, see [issue #685][]). The `--configuration Linux` flag is
necessary to ensure that the preprocessor definition `LINUX` is
defined (see [issue #673][]).
```sh
dotnet restore
dotnet publish --output bin --configuration Linux src/Microsoft.PowerShell.Linux.Host
```
PowerShell and all necessary components should now be in the `bin` folder.
[issue #673]: https://github.com/PowerShell/PowerShell/issues/673
[issue #685]: https://github.com/PowerShell/PowerShell/issues/685
+37
View File
@@ -0,0 +1,37 @@
Build PowerShell on OS X
========================
This guide supplements the [Linux instructions](./linux.md), as
building on OS X is almost identical.
Please keep in mind that we do not yet routinely test on OS X, but
some developers use PowerShell on 10.10 and 10.11.
Environment
===========
You will want [Homebrew](http://brew.sh/), the missing package manager
for OS X. Once installed, use `brew` to install the following
dependencies.
```sh
brew install openssl cmake wget
```
Instead of using .NET CLI's Ubuntu package feed, you will want to use
the official PKG installer.
```sh
wget https://dotnetcli.blob.core.windows.net/dotnet/beta/Installers/Latest/dotnet-dev-osx-x64.latest.pkg
open ./dotnet-dev-osx-x64.latest.pkg
```
Then follow the wizard's instructions to complete installation.
Build using our module
======================
Instead of installing the Ubuntu package of PowerShell, download the
`pkg` from our GitHub releases page using your browser, complete the
wizard, start a `powershell` session, and use `Start-PSBuild` from the
module.
+106
View File
@@ -0,0 +1,106 @@
PowerShell Remoting Protocol
============================
This guide supplements the [Linux instructions](./linux.md), as
building PowerShell Remoting Protocol (PSRP) support first requires
PowerShell on Linux built.
PSRP communication is tunneled through the Open Management
Infrastructure (OMI) using the [`omi-provider`][].
> PSRP has been observed working on OS X, but the changes made to OMI to
> accomplish this are not even beta-ready and need to be done correctly. They
> exist on the `andschwa-osx` branch of the OMI repository.
[omi-provider]: https://github.com/PowerShell/psl-omi-provider/
Environment
===========
Toolchain Setup
---------------
PSRP requires the following additional packages:
```sh
sudo apt-get install libpam0g-dev libssl-dev libcurl4-openssl-dev libboost-filesystem-dev
```
Git Setup
---------
Two additional submodules need to be initialized:
```sh
git submodule update --init -- src/omi src/omi-provider
```
The `src/omi` submodule requires your GitHub user to have joined the
Microsoft organization. If it fails to check out, Git will give up and
not check out further submodules either. Please follow the
instructions on the [Open Source Hub][].
[Open Source Hub]: https://opensourcehub.microsoft.com/articles/how-to-join-microsoft-github-org-self-service
Building
========
Run `./omibuild.sh` to build OMI and the provider.
This script first builds OMI in developer mode:
```sh
pushd src/omi/Unix
./configure --dev
make -j
popd
```
Then it builds and registers the provider:
```sh
pushd src/omi-provider
cmake -DCMAKE_BUILD_TYPE=Debug .
make -j
popd
```
The provider maintains its own native host library to initialize the
CLR, but there are plans to refactor .NET's packaged host as a shared
library.
Running
-------
Some initial setup on Windows is required. Open an administrative command
prompt and execute the following:
```cmd
winrm set winrm/config/Client @{AllowUnencrypted="true"}
winrm set winrm/config/Client @{TrustedHosts="*"}
```
> You can also set the `TrustedHosts` to include the target's IP address.
Then on Linux, launch `omiserver` (after building with the
instructions above):
```sh
./psrp.sh
```
Now in a PowerShell prompt on Windows (opened after setting the WinRM client
configurations):
```powershell
Enter-PSSession -ComputerName <IP address of Linux machine> -Credential $cred -Authentication basic
```
> The `$cred` variable can be empty; a credentials prompt will appear, enter
> any fake credentials you wish as authentication is not yet implemented.
The IP address of the Linux machine can be obtained with:
```sh
ip -f inet addr show dev eth0
```
+75
View File
@@ -0,0 +1,75 @@
Build PowerShell on Windows for .NET Core
=========================================
This guide will walk you through building PowerShell on Windows,
targetting .NET Core. We'll start by showing how to set up your
environment from scratch.
Environment
===========
These instructions are tested on Windows 10 and Windows Server 2012
R2, though they should work anywhere the dependencies work.
.NET CLI
--------
We use the [.NET Command Line Interface][dotnet-cli] (`dotnet`) to
build PowerShell. The following script will install `dotnet` and add
it to your PowerShell session's path:
```powershell
Invoke-WebRequest -Uri https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/install.ps1 -OutFile install.ps1
./install.ps1 -version 1.0.0.001888
$env:Path += ";$env:LocalAppData\Microsoft\dotnet\cli
```
If you have any problems installing `dotnet`, please see their
[documentation][cli-docs].
If you are using Windows 7, Windows Server 2008 or Windows Server 2012
you will also need to install
[Visual C++ Redistributable for Visual Studio 2012 Update 4][redist-2012]
and [Visual C++ Redistributable for Visual Studio 2015][redist-2015].
The version of .NET CLI is very important, you want a recent build of
1.0.0 (**not** 1.0.1).
Previous installations of DNX, `dnvm`, or older installations of .NET
CLI can cause odd failures when running. Please check your version.
[dotnet-cli]: https://github.com/dotnet/cli#new-to-net-cli
[cli-docs]: https://dotnet.github.io/getting-started/
[redist-2012]: https://www.microsoft.com/en-us/download/confirmation.aspx?id=30679
[redist-2015]: https://www.microsoft.com/en-us/download/details.aspx?id=48145
Git Setup
---------
Please clone the superproject (this repo) and initialize a subset of
the submodules:
```sh
git clone https://github.com/PowerShell/PowerShell.git
cd PowerShell
git submodule update --init -- src/windows-build src/Microsoft.PowerShell.Linux.Host/Modules/Pester
```
Build using our module
======================
We maintain a `PowerShellGitHubDev.psm1` PowerShell module with the
function `Start-PSBuild` to build PowerShell.
```powershell
Import-Module ./PowerShellGitHubDev.psm1
Start-PSBuild
```
Congratulations! If everything went right, PowerShell is now built and
executable as `./bin/powershell.exe`.
> The cross-platform host has built-in documentation via `--help`.
You can run our cross-platform Pester tests with `./bin/powershell.exe
-c "Invoke-Pester test/powershell"`.
+89
View File
@@ -0,0 +1,89 @@
Build PowerShell on Windows for .NET Full
=========================================
This guide supplements the
[Windows .NET Core instructions](./windows-core.md), as building the
.NET 4.5.1 (desktop) version is nearly identical.
Environment
===========
In addition to the dependencies specified in the .NET Core
instructions, we need:
Install the Visual C++ Compiler via Visual Studio 2015.
-------------------------------------------------------
This component is required to compile the native `powershell.exe` host.
This is an optionally installed component, so you may need to run the
Visual Studio installer again.
If you don't have any Visual Studio installed, you can use
[Visual Studio 2015 Community Edition][vs].
> Compiling with older versions should work, but we don't test it.
**Troubleshooting note:** If `cmake` says that it cannot determine the
`C` and `CXX` compilers, you either don't have Visual Studio, or you
don't have the Visual C++ Compiler component installed.
[vs]: https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx
Install CMake and add it to `PATH`.
-----------------------------------
You can install it from [Chocolatey][] or [manually][].
```
choco install cmake.portable
```
[Chocolatey]: https://chocolatey.org/packages/cmake.portable
[manually]: https://cmake.org/download/
Build using our module
======================
Use `Start-PSBuild -FullCLR` from the `PowerShellGitHubDev.psm1`
module. The bits will be published to `binFull`.
While building is easy, running FullCLR version is not as simple as
CoreCLR version.
If you just run ~~`.\binFull\powershell.exe`~~, you will get a
`powershell` process, but all the interesting DLLs (i.e.
`System.Management.Automation.dll`) would be loaded from the GAC, not
your `binFull` build directory.
[@lzybkr](https://github.com/lzybkr) wrote a module to deal with it
and run side-by-side.
```powershell
Start-DevPSGithub -binDir $pwd\binFull
```
The default for `powershell.exe` that **we build** is x86. See
[issue #683][].
There is a separate execution policy registry key for x86, and it's
likely that you didn't ~~bypass~~ enable it. From **powershell.exe
(x86)** run:
```
Set-ExecutionPolicy Bypass
```
[issue #683]: https://github.com/PowerShell/PowerShell/issues/683
Build manually
==============
The build logic is relatively simple and contains the following steps:
- building managed DLLs: `dotnet publish --runtime net451`
- generating Visual Studio project: `cmake -G "$cmakeGenerator"`
- building `powershell.exe` from generated solution: `msbuild
powershell.sln`
Please don't hesitate to experiment.
+44
View File
@@ -0,0 +1,44 @@
Debugging
=========
VS Code
-------
[Experimental .NET Core Debugging in VS Code][core-debug] enables
cross-platform debugging with the [Visual Studio Code][vscode] editor.
This is made possible by the [OmniSharp][] extension for VS Code.
Please review their [detailed instructions][vscclrdebugger]. In
addition to being able to build PowerShell, you need:
- C# Extension for VS Code installed
- `powershell` executable in your path (self-host if not on Windows)
The committed `.vscode` folder in the root of this repository contains
the `launch.json` and `tasks.json` files which provide Core PowerShell
debugging configurations and a build task.
The "build" task will run `Start-PSBuild`.
The ".NET Core Launch" configuration will build and start a
`powershell` process, with `justMyCode` disabled, and `stopAtEntry`
enabled. The debugger is highly experimental, so if it does not break
at `Main`, try again.
Note that the debugger does not yet provide `stdin` handles, so once
`ReadKey` is called in the `ReadLine` loop, `System.Console` will
throw exceptions. The options around this are 1) provide
`[ "-c", "... ; exit" ]` to the "Launch" configuration's `args` so
that the `ReadLine` listener is never called, 2) ignore the exceptions
and only debug code before the listener, or 3) use the "Attach"
configuration.
The ".NET Core Attach" configuration will start listening for a
process named `powershell`, and will attach to it. If you need more
fine grained control, replace `processName` with `processId` and
provide a PID. (Please be careful not to commit such a change).
[core-debug]: https://blogs.msdn.microsoft.com/visualstudioalm/2016/03/10/experimental-net-core-debugging-in-vs-code/
[vscode]: https://code.visualstudio.com/
[OmniSharp]: https://github.com/OmniSharp/omnisharp-vscode
[vscclrdebugger]: http://aka.ms/vscclrdebugger
+7 -2
View File
@@ -20,6 +20,8 @@ During the install process, choose these recommended settings:
* Use Windows' default console window
* Enable file system caching
[Git for Windows]: https://git-scm.com/download/win
#### Linux
Install via the package manager:
@@ -42,12 +44,15 @@ changes, and issue a pull request.
#### Githug
[Githug](https://github.com/Gazler/githug) is a great gamefied way to learn git in couple hours.
After finishing 50+ real-world scenarios you will have a pretty good idea about what and when you can do with git.
[Githug](https://github.com/Gazler/githug) is a great gamified way to
learn Git in couple hours. After finishing 50+ real-world scenarios
you will have a pretty good idea about what and when you can do with
Git.
## Cheatsheets
#### Git pretty
[So you have a mess on your hands?](http://justinhileman.info/article/git-pretty/)
## Scenarios
+39
View File
@@ -0,0 +1,39 @@
Package installation instructions
=================================
Supports Ubuntu 14.04, CentOS 7.1, and OS X 10.11.
Once the package is installed, `powershell` will be in your path,
ready to be launched from a terminal. It will read
`~/.powershell/profile.ps1` for your user profile, and
`/usr/local/share/powershell/PSL_profile.ps1` for the system profile.
Similarly, it will search `~/.powershell/Modules` and
`/usr/local/share/powershell/Modules` for user and system modules.
Ubuntu 14.04
============
Using a stock Ubuntu 14.04 image, download the
`powershell_0.2.0-1_amd64.deb` file, and then execute the following:
```sh
sudo apt-get install libunwind8 libicu52
sudo dpkg -i powershell_0.2.0-1_amd64.deb
```
CentOS 7.1
==========
Using a stock CentOS 7.1 image, download the
`powershell-0.2.0-1.x86_64.rpm` file, and then execute the following:
```sh
sudo yum install powershell-0.2.0-1.x86_64.rpm
```
OS X 10.11
==========
Using an OS X 10.11 machine, download the `powershell-0.2.0.pkg` file,
double-click it, and follow the prompts.
+25
View File
@@ -0,0 +1,25 @@
Artifact installation instructions
==================================
We publish an archive with CoreCLR and FullCLR bits on every CI build
with [AppVeyor][].
[appveyor]: https://ci.appveyor.com/project/PowerShell/powershell-linux
CoreCLR artifacts
=================
* Download zip package from **artifacts** tab of the particular build.
* Unblock zip file: right-click in file explorer -> properties ->
check 'Unblock' box -> apply
* Extract zip file to `bin` directory
* `./bin/powershell.exe`
FullCLR artifacts
=================
* Download zip package from **artifacts** tab of the particular build.
* Unblock zip file: right-click in file explorer -> properties ->
check 'Unblock' box -> apply
* Extract zip file to `$in` directory
* `Start-DevPSGithub -binDir bin`
-1
View File
@@ -1 +0,0 @@
#xUnit Testing Guide
-54
View File
@@ -1,54 +0,0 @@
# docker run magrathea with a non-interactive tty
monad-run()
{
monad-docker-run "--tty" $*
}
# docker run magrathea with interactive tty
monad-it()
{
monad-docker-run "--interactive --tty" $*
}
monad-attach()
{
monad-docker-run "--attach STDOUT --attach STDERR" $*
}
# runs ephemeral andschwa/magrathea docker container with local
# directory mounted and workdir set to /opt
monad-docker-run()
{
local CONSOLE=$1
shift 1
docker run --rm \
--volume $(pwd)/:/opt/src \
--workdir /opt/src \
$CONSOLE \
andschwa/magrathea:latest \
bash -c "$(monad-impersonate) bash -c '$*'"
}
# creates new user in container matching the local user so that
# artifacts will be owned by the local user; set IMPERSONATE to false
# to disable and run as root, defaults to true
if [[ ! $IMPERSONATE ]]; then IMPERSONATE=true; fi
monad-impersonate()
{
if ! $IMPERSONATE; then return; fi
local CUID=$(id -u)
local CUSER=$(id -un)
local CGID=$(id -g)
local CGROUP=$(id -gn)
# default docker-machine VM does not change
if [[ $OSTYPE == darwin* ]]; then
CUID=1000
CUSER=docker
CGID=50
CGROUP=staff
fi
echo \
groupadd -o -f -g $CGID $CGROUP '&&' \
useradd -u $CUID -g $CGID -G sudo -d /opt $CUSER '&&' \
sudo --set-home -u $CUSER -g $CGROUP --
}
@@ -1 +1,3 @@
*.a
*.a
*.so
*.dylib
+11
View File
@@ -0,0 +1,11 @@
Testing
=======
The tests are organized by testing language. Thus Pester tests, which
are written in the PowerShell language, are in
[./powershell](./powershell) and xUnit tests, written in C#, are in
[./csharp](./csharp). The sanity tests for the Full .NET build of
PowerShell are in [./fullclr](./fullclr), and the third-party
[shebang][] test is in [./shebang](./shebang).
[shebang]: https://en.wikipedia.org/wiki/Shebang_(Unix)
+1 -1
View File
@@ -1,6 +1,6 @@
# xUnit Tests
This tests are completely Linux specific.
These tests are completely Linux specific.
Every test class *must* belong to
`[Collection("AssemblyLoadContext")]`. This ensures that PowerShell's
+157
View File
@@ -0,0 +1,157 @@
Pester Testing Test Guide
=========================
Who this is for
---------------
Cmdlet behavior is validated using the Pester testing framework. The
purpose of this document is to create a single standard to maximize
unit test coverage while minimizing confusion on expectations. What
follows is a working document intended to guide those writing Pester
unit tests for PowerShell.
Unit testing is done not only to validate that the block of code works
as expected, but also to assist the developer to know precisely where
in the code to look; in some cases, seeing the source code may inspire
better unit tests. In many cases, a unit test *is* the only documented
specification. Fortunately, the MSDN is a great source of information
about Cmdlets.
Test suites need to be created and many cmdlets added and unit-tested.
The following list is to be used to guide the thought process of the
developer in writing a suite in minimal time, while enhancing quality.
Test suites should proceed as functional and system tests of the
cmdlets, and the code treated as a black box for the purpose of test
suite design.
### Portability
Some tests simply must be tied to certain platforms. Use Pester's
`-Skip` directive on an `It` statement to do this. For instance to run
the test only on Windows:
```powershell
It "Should do something on Windows" -Skip:($IsLinux -Or $IsOSX) { ... }
```
Or only on Linux and OS X:
```powershell
It "Should do something on Linux" -Skip:$IsWindows { ... }
```
### Use of Mocks
It is often necessary for the code to interact with the system or
other components. When possible, use Mock objects to facilitate this
in order to minimize external dependencies. Note: creating a Mock in
Powershell on Linux causes PowerShell to look at the Mock, never
actually hitting any C# code. Cmdlets cannot be tested using Mocks.
### Aliases
Each cmdlet with an alias must be tested with all of its aliases at
least once to verify the code path calls the original function.
Testing Standards
-----------------
### Readability
Every effort should be made to maximize readability of code. Code is
written for the developer in the future to debug- not for the
developer writing the code.
1) When assertions are on consecutive lines, the pipes should line up:
```sh
MyFirstCondition | Should Be 0
MySecondCondition | Should Be 1
```
This is less readable than:
```sh
MyFirstCondition | Should Be 0
MySecondCondition | Should Be 1
```
So the second section of code should instead be used. The same style
should be followed for assignments of variables on consecutive lines:
```sh
$var1 = <expression 1>
$variable2 = <expression 2>
$var3 = <expression 3>
$typeCollection1 = <expression 4>
$object1 = <expression>
... etc
```
is much less readable than
```sh
$var1 = <expression 1>
$variable2 = <expression 2>
$var3 = <expression 3>
$typeCollection1 = <expression 4>
$object1 = <expression 5>
... etc
```
So all assignment statements must be aligned.
Other style standards are no less important to readability of the code:
- Use readable and meaningful variable name when assigning variables.
- Do not make large functions. Tests should be simple: define ->
manipulate -> assert
- Do not use tabs. Tabs are rendered differently depending upon the
machine. This greatly affects readability.
- Remove the first 3 auto-generated lines of each .Tests.ps1 file.
This is created automatically by Pester and is unnecessary. Each
.Test.ps1 file should begin with a Describe block.
- Discard the auto-generated function file that is generated in tandem
with the .Tests.ps1 file
- Name the test file "Test-<cmdlet name > when you create a new test
fixture.
- Each test describes a behavior- use the word "Should" at the
beginning of each test description- so it reads "It 'Should..."
### Basic Unit Tests
The following table should suffice to inspire in the developer sufficient content to create a suite of tests.
test # | test name | entry criteria/setup | exit criteria/assertion
-------|-----------|----------------------|------------------------
01 | Should be able to be called | without params (if applicable) | no throw
02 | Should be able to be called | minimal required params | no throw, expected output
03 | Should be able to use the X alias | minimal required params | no throw, expected output
04 | Should return the proper data type | required params | no throw, proper data type
05 | Should be able to accept piped input | piped input | expected output
06 | Should be able to call using the X parameter | use X parameter | no throw, expected output
07 | Should be able to call using the Y parameter | use Y parameter | no throw, expected output
08 | Should be able to call using the Z parameter | use Z parameter | no throw, expected output
09 | Should throw under condition X | create condition X | Throw error x
10 | Should throw under condition Y | create condition Y | Throw error y
11 | Should throw under condition Z | create condition Z | Throw error z
These are the **basic** unit tests required to verify the
functionality of any Cmdlet. If the above questions cannot be answered
for each Cmdlet, then they cannot be verified to work.
Look at the existing suites of pester tests located within
this directory and use that as inspiration.
Running Pester Tests
--------------------
Go to the top level of the PowerShell repository and run:
`./bin/powershell -c "Invoke-Pester test/powershell"`