public function run()
    {
        // Set the total count to zero
        $this->totalCount = 0;

        // Load the suites defined in the options
        $suites = $this->options->suites;

        // Check if a suite name has been passed via the command line
        if ($suite = $this->options->suite) {
            // If the suite hasn't been defined, throw an exception
            if (!$this->options->suites->{$suite}) {
                throw new TestNotFoundException('The suite '.$suite.' is not defined');
            }

            // Overwrite the array of suites, so that only the passed
            // suite is run
            $suites = [
                $suite => $this->options->suites->{$suite},
            ];
        }

        // If arguments exist, then we create a new suite from the
        // files/directories passed as arguments
        if ($this->args) {
            $suites = [
                'tests' => $this->args,
            ];
        }

        // Loop through each of the suites
        foreach ($suites as $suite => $dirs) {
            // Reset the runner's tests
            $this->tests = [];

            // Load the tests for the suite
            $this->loadTests($dirs);

            // Get the number of tests and increment the total count
            $total = count($this->tests);
            $this->totalCount += $total;

            // Get the suite name
            $name = Str::title($suite);

            // Output a message to the user
            echo "\n";
            echo $this->output->gray->render("Running $total tests in suite $name...");

            // Render the table of tests
            $this->output->table();

            // If the random option is set, shuffle the array of tests
            if ($this->options->random === true) {
                shuffle($this->tests);
            }

            // Loop through each of the tests
            foreach ($this->tests as $test) {
                // Run the test inside a try/catch block so that we can
                // include errors in results without stopping testing
                try {
                    $test->run();
                } catch (Exception $e) {
                    $bits = explode('\\', get_class($e));
                    // Mark the test as errored
                    $test->error(array_pop($bits).': '.$e->getMessage());
                }
            }
        }

        // Output the results to the CLI
        $this->output->results();
    }