diff --git a/Cargo.toml b/Cargo.toml
index 39b38b9..db2f366 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,6 +12,9 @@ categories = ["development-tools::testing"]
 keywords = ["cli", "testing", "assert"]
 build = "build.rs"
 
+[[bin]]
+name = "assert_fixture"
+
 [dependencies]
 colored = "1.5"
 difference = "1.0"
diff --git a/src/assert.rs b/src/assert.rs
index 74e45c0..cb545cc 100644
--- a/src/assert.rs
+++ b/src/assert.rs
@@ -1,4 +1,5 @@
 use environment::Environment;
+use error_chain::ChainedError;
 use errors::*;
 use output::{OutputAssertion, OutputKind};
 use std::default;
@@ -7,6 +8,20 @@ use std::path::PathBuf;
 use std::process::{Command, Stdio};
 use std::vec::Vec;
 
+fn find_cargo() -> String {
+    let which_cargo = Command::new("which").arg("cargo")
+        .output().expect("Cannot exectute `which` to find `cargo`.");
+
+    if !which_cargo.status.success() {
+        panic!("Could not find `cargo` command");
+    }
+
+    String::from_utf8(which_cargo.stdout)
+        .expect("Path to `cargo` is not UTF-8. This is currently unsupported by assert_cli.")
+        .trim()
+        .to_string()
+}
+
 /// Assertions for a specific command.
 #[derive(Debug)]
 pub struct Assert {
@@ -24,11 +39,13 @@ impl default::Default for Assert {
     ///
     /// Defaults to asserting _successful_ execution.
     fn default() -> Self {
+        let cargo_path = find_cargo();
+        let args = vec!["run", "--quiet", "--"]
+            .into_iter()
+            .map(String::from);
+
         Assert {
-            cmd: vec!["cargo", "run", "--"]
-                .into_iter()
-                .map(String::from)
-                .collect(),
+            cmd: vec![cargo_path].into_iter().chain(args).collect(),
             env: Environment::inherit(),
             current_dir: None,
             expect_success: Some(true),
@@ -51,11 +68,13 @@ impl Assert {
     ///
     /// Defaults to asserting _successful_ execution.
     pub fn cargo_binary(name: &str) -> Self {
+        let cargo_path = find_cargo();
+        let args = vec!["run", "--quiet", "--bin", name, "--"]
+            .into_iter()
+            .map(String::from);
+
         Assert {
-            cmd: vec!["cargo", "run", "--bin", name, "--"]
-                .into_iter()
-                .map(String::from)
-                .collect(),
+            cmd: vec![cargo_path].into_iter().chain(args).collect(),
             ..Self::default()
         }
     }
@@ -308,7 +327,9 @@ impl Assert {
             None => command,
         };
 
-        let mut spawned = command.spawn()?;
+        let mut spawned = command
+            .spawn()
+            .chain_err(|| ErrorKind::SpawnFailed(self.cmd.clone()))?;
 
         if let Some(ref contents) = self.stdin_contents {
             spawned
@@ -365,7 +386,7 @@ impl Assert {
     /// ```
     pub fn unwrap(self) {
         if let Err(err) = self.execute() {
-            panic!("{}", err);
+            panic!("{}", err.display_chain());
         }
     }
 }
diff --git a/src/bin/assert_fixture.rs b/src/bin/assert_fixture.rs
new file mode 100644
index 0000000..f22ba0c
--- /dev/null
+++ b/src/bin/assert_fixture.rs
@@ -0,0 +1,31 @@
+#[macro_use]
+extern crate error_chain;
+
+use std::env;
+use std::process;
+
+error_chain! {
+    foreign_links {
+        Env(env::VarError);
+        ParseInt(std::num::ParseIntError);
+    }
+}
+
+fn run() -> Result<()> {
+    if let Ok(text) = env::var("stdout") {
+        println!("{}", text);
+    }
+    if let Ok(text) = env::var("stderr") {
+        eprintln!("{}", text);
+    }
+
+    let code = env::var("exit")
+        .ok()
+        .map(|v| v.parse::<i32>())
+        .map_or(Ok(None), |r| r.map(Some))
+        .chain_err(|| "Invalid exit code")?
+        .unwrap_or(0);
+    process::exit(code);
+}
+
+quick_main!(run);
diff --git a/src/errors.rs b/src/errors.rs
index af9ab5e..ab0f7b1 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -6,6 +6,14 @@ error_chain! {
         Fmt(::std::fmt::Error);
     }
     errors {
+        SpawnFailed(cmd: Vec<String>) {
+            description("Spawn failed")
+            display(
+                "{}: (command `{}` failed to run)",
+                ERROR_PREFIX,
+                cmd.join(" "),
+            )
+        }
         StatusMismatch(cmd: Vec<String>, expected: bool, out: String, err: String) {
             description("Wrong status")
             display(
diff --git a/tests/cargo.rs b/tests/cargo.rs
new file mode 100644
index 0000000..405532d
--- /dev/null
+++ b/tests/cargo.rs
@@ -0,0 +1,35 @@
+extern crate assert_cli;
+
+#[test]
+fn main_binary() {
+    assert_cli::Assert::main_binary()
+        .with_env(assert_cli::Environment::inherit().insert("stdout", "42"))
+        .stdout()
+        .is("42")
+        .stderr()
+        .is("")
+        .unwrap();
+}
+
+#[test]
+fn cargo_binary() {
+    assert_cli::Assert::cargo_binary("assert_fixture")
+        .with_env(assert_cli::Environment::inherit().insert("stdout", "42"))
+        .stdout()
+        .is("42")
+        .stderr()
+        .is("")
+        .unwrap();
+}
+
+
+#[test]
+fn works_with_empty_env() {
+    assert_cli::Assert::main_binary()
+        .with_env(assert_cli::Environment::empty())
+        .unwrap();
+
+    assert_cli::Assert::cargo_binary("assert_fixture")
+        .with_env(assert_cli::Environment::empty())
+        .unwrap();
+}