blob: 6486dbde8a8b6f9e7a2b2363b2928dba3e963af5 [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Testing the compiler - Rust Compiler Development Guide</title>
<!-- Custom HTML head -->
<meta name="description" content="A guide to developing the Rust compiler (rustc)">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" id="highlight-css" href="../highlight.css">
<link rel="stylesheet" id="tomorrow-night-css" href="../tomorrow-night.css">
<link rel="stylesheet" id="ayu-highlight-css" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<!-- Provide site root and default themes to javascript -->
<script>
const path_to_root = "../";
const default_light_theme = "light";
const default_dark_theme = "navy";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
let theme = localStorage.getItem('mdbook-theme');
let sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
let theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
let sidebar = null;
const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Rust Compiler Development Guide</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/rust-lang/rustc-dev-guide" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://github.com/rust-lang/rustc-dev-guide/edit/master/src/tests/intro.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="testing-the-compiler"><a class="header" href="#testing-the-compiler">Testing the compiler</a></h1>
<ul>
<li><a href="#kinds-of-tests">Kinds of tests</a>
<ul>
<li><a href="#compiletest">Compiletest</a></li>
<li><a href="#package-tests">Package tests</a></li>
<li><a href="#tidy">Tidy</a></li>
<li><a href="#formatting">Formatting</a></li>
<li><a href="#book-documentation-tests">Book documentation tests</a></li>
<li><a href="#documentation-link-checker">Documentation link checker</a></li>
<li><a href="#dist-check">Dist check</a></li>
<li><a href="#tool-tests">Tool tests</a></li>
<li><a href="#ecosystem-testing">Ecosystem testing</a></li>
<li><a href="#performance-testing">Performance testing</a></li>
<li><a href="#codegen-backend-testing">Codegen backend testing</a></li>
</ul>
</li>
<li><a href="#miscellaneous-information">Miscellaneous information</a></li>
<li><a href="#further-reading">Further reading</a></li>
</ul>
<p>The Rust project runs a wide variety of different tests, orchestrated by the
build system (<code>./x test</code>). This section gives a brief overview of the different
testing tools. Subsequent chapters dive into <a href="running.html">running tests</a> and
<a href="adding.html">adding new tests</a>.</p>
<h2 id="kinds-of-tests"><a class="header" href="#kinds-of-tests">Kinds of tests</a></h2>
<p>There are several kinds of tests to exercise things in the Rust distribution.
Almost all of them are driven by <code>./x test</code>, with some exceptions noted below.</p>
<h3 id="compiletest"><a class="header" href="#compiletest">Compiletest</a></h3>
<p>The main test harness for testing the compiler itself is a tool called
<a href="compiletest.html">compiletest</a>.</p>
<p><a href="compiletest.html">compiletest</a> supports running different styles of tests, organized into <em>test
suites</em>. A <em>test mode</em> may provide common presets/behavior for a set of <em>test
suites</em>. <a href="compiletest.html">compiletest</a>-supported tests are located in the <a href="https://github.com/rust-lang/rust/tree/master/tests"><code>tests</code></a> directory.</p>
<p>The <a href="compiletest.html">Compiletest chapter</a> goes into detail on how to use this tool.</p>
<blockquote>
<p>Example: <code>./x test tests/ui</code></p>
</blockquote>
<h3 id="package-tests"><a class="header" href="#package-tests">Package tests</a></h3>
<p>The standard library and many of the compiler packages include typical Rust
<code>#[test]</code> unit tests, integration tests, and documentation tests. You can pass a
path to <code>./x test</code> for almost any package in the <code>library/</code> or <code>compiler/</code>
directory, and <code>x</code> will essentially run <code>cargo test</code> on that package.</p>
<p>Examples:</p>
<div class="table-wrapper"><table><thead><tr><th>Command</th><th>Description</th></tr></thead><tbody>
<tr><td><code>./x test library/std</code></td><td>Runs tests on <code>std</code> only</td></tr>
<tr><td><code>./x test library/core</code></td><td>Runs tests on <code>core</code> only</td></tr>
<tr><td><code>./x test compiler/rustc_data_structures</code></td><td>Runs tests on <code>rustc_data_structures</code></td></tr>
</tbody></table>
</div>
<p>The standard library relies very heavily on documentation tests to cover its
functionality. However, unit tests and integration tests can also be used as
needed. Almost all of the compiler packages have doctests disabled.</p>
<p>All standard library and compiler unit tests are placed in separate <code>tests</code> file
(which is enforced in <a href="https://github.com/rust-lang/rust/blob/master/src/tools/tidy/src/unit_tests.rs">tidy</a>). This ensures that when the test
file is changed, the crate does not need to be recompiled. For example:</p>
<pre><code class="language-rust ignore">#[cfg(test)]
mod tests;</code></pre>
<p>If it wasn't done this way, and you were working on something like <code>core</code>, that
would require recompiling the entire standard library, and the entirety of
<code>rustc</code>.</p>
<p><code>./x test</code> includes some CLI options for controlling the behavior with these
package tests:</p>
<ul>
<li><code>--doc</code> — Only runs documentation tests in the package.</li>
<li><code>--no-doc</code> — Run all tests <em>except</em> documentation tests.</li>
</ul>
<h3 id="tidy"><a class="header" href="#tidy">Tidy</a></h3>
<p>Tidy is a custom tool used for validating source code style and formatting
conventions, such as rejecting long lines. There is more information in the
<a href="../conventions.html#formatting">section on coding conventions</a>.</p>
<blockquote>
<p>Examples: <code>./x test tidy</code></p>
</blockquote>
<h3 id="formatting"><a class="header" href="#formatting">Formatting</a></h3>
<p>Rustfmt is integrated with the build system to enforce uniform style across the
compiler. The formatting check is automatically run by the Tidy tool mentioned
above.</p>
<p>Examples:</p>
<div class="table-wrapper"><table><thead><tr><th>Command</th><th>Description</th></tr></thead><tbody>
<tr><td><code>./x fmt --check</code></td><td>Checks formatting and exits with an error if formatting is needed.</td></tr>
<tr><td><code>./x fmt</code></td><td>Runs rustfmt across the entire codebase.</td></tr>
<tr><td><code>./x test tidy --bless</code></td><td>First runs rustfmt to format the codebase, then runs tidy checks.</td></tr>
</tbody></table>
</div>
<h3 id="book-documentation-tests"><a class="header" href="#book-documentation-tests">Book documentation tests</a></h3>
<p>All of the books that are published have their own tests, primarily for
validating that the Rust code examples pass. Under the hood, these are
essentially using <code>rustdoc --test</code> on the markdown files. The tests can be run
by passing a path to a book to <code>./x test</code>.</p>
<blockquote>
<p>Example: <code>./x test src/doc/book</code></p>
</blockquote>
<h3 id="documentation-link-checker"><a class="header" href="#documentation-link-checker">Documentation link checker</a></h3>
<p>Links across all documentation is validated with a link checker tool,
and it can be invoked so:</p>
<pre><code class="language-console">./x test linkchecker
</code></pre>
<p>This requires building all of the documentation, which might take a while.</p>
<h3 id="dist-check"><a class="header" href="#dist-check">Dist check</a></h3>
<p><code>distcheck</code> verifies that the source distribution tarball created by the build
system will unpack, build, and run all tests.</p>
<blockquote>
<p>Example: <code>./x test distcheck</code></p>
</blockquote>
<h3 id="tool-tests"><a class="header" href="#tool-tests">Tool tests</a></h3>
<p>Packages that are included with Rust have all of their tests run as well. This
includes things such as cargo, clippy, rustfmt, miri, bootstrap (testing the
Rust build system itself), etc.</p>
<p>Most of the tools are located in the <a href="https://github.com/rust-lang/rust/tree/master/src/tools/"><code>src/tools</code></a> directory. To run the tool's
tests, just pass its path to <code>./x test</code>.</p>
<blockquote>
<p>Example: <code>./x test src/tools/cargo</code></p>
</blockquote>
<p>Usually these tools involve running <code>cargo test</code> within the tool's directory.</p>
<p>If you want to run only a specified set of tests, append <code>--test-args FILTER_NAME</code> to the command.</p>
<blockquote>
<p>Example: <code>./x test src/tools/miri --test-args padding</code></p>
</blockquote>
<p>In CI, some tools are allowed to fail. Failures send notifications to the
corresponding teams, and is tracked on the <a href="https://rust-lang-nursery.github.io/rust-toolstate/">toolstate website</a>. More information
can be found in the <a href="https://forge.rust-lang.org/infra/toolstate.html">toolstate documentation</a>.</p>
<h3 id="ecosystem-testing"><a class="header" href="#ecosystem-testing">Ecosystem testing</a></h3>
<p>Rust tests integration with real-world code to catch regressions and make
informed decisions about the evolution of the language. There are several kinds
of ecosystem tests, including Crater. See the <a href="ecosystem.html">Ecosystem testing
chapter</a> for more details.</p>
<h3 id="performance-testing"><a class="header" href="#performance-testing">Performance testing</a></h3>
<p>A separate infrastructure is used for testing and tracking performance of the
compiler. See the <a href="perf.html">Performance testing chapter</a> for more details.</p>
<h3 id="codegen-backend-testing"><a class="header" href="#codegen-backend-testing">Codegen backend testing</a></h3>
<p>See <a href="./codegen-backend-tests/intro.html">Codegen backend testing</a>.</p>
<h2 id="miscellaneous-information"><a class="header" href="#miscellaneous-information">Miscellaneous information</a></h2>
<p>There are some other useful testing-related info at <a href="misc.html">Misc info</a>.</p>
<h2 id="further-reading"><a class="header" href="#further-reading">Further reading</a></h2>
<p>The following blog posts may also be of interest:</p>
<ul>
<li>brson's classic <a href="https://brson.github.io/2017/07/10/how-rust-is-tested">"How Rust is tested"</a></li>
</ul>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../building/optimized-build.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../tests/running.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../building/optimized-build.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../tests/running.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
<script src="../mermaid.min.js"></script>
<script src="../mermaid-init.js"></script>
</div>
</body>
</html>