{
    "componentChunkName": "component---src-components-page-template-jsx",
    "path": "/guides/testing-and-catch",
    "result": {"data":{"mdx":{"id":"8c817822-88b1-532c-9c6b-1f07e637b0d3","body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"section\": \"Guides\",\n  \"chapter\": \"Main Codebase\",\n  \"title\": \"Testing and Catch\",\n  \"description\": \"How to write automated tests, with Catch examples in C++.\",\n  \"slug\": \"/guides/testing-and-catch\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"This page combines general testing guidance used by the project with concrete examples using the Catch (Catch2) framework. The first section considers the general testing philosophy and approach, while the second section guides the user on framework-specific examples and tips using Catch and C++.\"), mdx(\"h2\", {\n    \"id\": \"writing-tests\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#writing-tests\",\n    \"aria-label\": \"writing tests permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Writing Tests\"), mdx(\"p\", null, \"This section contains general guidance about unit testing that applies regardless of the testing framework. For the concrete examples in this guide we use the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"add\"), \" example in the \\\"A Basic Example\\\" section below.\"), mdx(\"h3\", {\n    \"id\": \"what-is-a-unit-test\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#what-is-a-unit-test\",\n    \"aria-label\": \"what is a unit test permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"What is a Unit Test?\"), mdx(\"p\", null, \"A unit test is a test of a small piece of a codebase \\u2014 a unit. Unit tests should exercise a single piece of code to validate its correctness. This contrasts with integration tests, which exercise the interactions of pieces of code together.\"), mdx(\"h3\", {\n    \"id\": \"anatomy-of-a-unit-test\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#anatomy-of-a-unit-test\",\n    \"aria-label\": \"anatomy of a unit test permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Anatomy of a Unit Test\"), mdx(\"p\", null, \"Basic pieces you need to create a unit test for a function:\"), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"A set of inputs for the function. These should match the function's parameters.\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"The expected outputs for each input (the \\\"ground truth\\\").\")), mdx(\"p\", null, \"The process is simply calling the function with inputs and verifying the outputs match expectations. For small examples we often keep inputs inline; for larger datasets keep them separate from test logic and document how they were generated.\"), mdx(\"h4\", {\n    \"id\": \"obtaining-expected-outputs\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h4\",\n    \"href\": \"#obtaining-expected-outputs\",\n    \"aria-label\": \"obtaining expected outputs permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Obtaining Expected Outputs\"), mdx(\"p\", null, \"For purely mathematical functions you can generate large input sets and verify expected outputs using a trusted implementation on another platform (for example using \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"numpy\"), \" in Python). For non-mathematical functions, enumerate categorical corner cases and cover them manually. Always document how generated data was produced and verified.\"), mdx(\"h3\", {\n    \"id\": \"testing-approach-and-philosophy\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#testing-approach-and-philosophy\",\n    \"aria-label\": \"testing approach and philosophy permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Testing Approach and Philosophy\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Tests should be simple and readable enough to be correct on inspection.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Make test cases independent \\u2014 one test's outcome should not affect another's.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Demonstrate how to use code via tests (they act as executable examples).\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Tests should be deterministic \\u2014 seed randomness and use multiple seeds where appropriate.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Follow the AAA structure: Arrange, Act, Assert.\")), mdx(\"h3\", {\n    \"id\": \"general-approach\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#general-approach\",\n    \"aria-label\": \"general approach permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"General Approach\"), mdx(\"p\", null, \"Write easy tests first, then add edge cases. After basic correctness is established, consider error handling and overflow behaviours and add regression tests for fixed bugs.\"), mdx(\"h3\", {\n    \"id\": \"regression-tests\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#regression-tests\",\n    \"aria-label\": \"regression tests permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Regression Tests\"), mdx(\"p\", null, \"When fixing bugs, add regression tests that would have failed before the fix. Label tests with comments referencing issues when relevant.\"), mdx(\"h3\", {\n    \"id\": \"black-box-vs-white-box-testing\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#black-box-vs-white-box-testing\",\n    \"aria-label\": \"black box vs white box testing permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Black Box vs White Box Testing\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Black box tests only consider inputs and outputs and are resilient to implementation changes.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"White box tests depend on internals and are more fragile to refactors.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Grey box testing is a middle ground and can be useful for achieving coverage while remaining maintainable.\")), mdx(\"h3\", {\n    \"id\": \"tdd-and-bdd\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#tdd-and-bdd\",\n    \"aria-label\": \"tdd and bdd permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"TDD and BDD\"), mdx(\"p\", null, \"Test-Driven Development (TDD) encourages writing tests first. Behaviour-Driven Development (BDD) uses \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Given/When/Then\"), \" language to make tests readable by all stakeholders. A mix of readable BDD-style examples and focused unit tests is a good balance.\"), mdx(\"h2\", {\n    \"id\": \"catch\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#catch\",\n    \"aria-label\": \"catch permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Catch\"), mdx(\"p\", null, mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/catchorg/Catch2\"\n  }, \"Catch\"), \" is the C++ testing framework which we use for our unit tests. In this guide we will go over the basics of Catch by completing a concrete example. This guide assumes familiarity with C++ and testing concepts.\"), mdx(\"p\", null, \"Note that the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/catchorg/Catch2/tree/devel/docs\"\n  }, \"Catch docs\"), \" should be the first thing to look at if you're wondering about a specific Catch-ism.\"), mdx(\"h3\", {\n    \"id\": \"a-basic-example\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#a-basic-example\",\n    \"aria-label\": \"a basic example permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"A Basic Example\"), mdx(\"p\", null, \"Catch test cases have a few components. The most important is the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"TEST_CASE(..)\"), \" macro, which wraps around groups of associated tests. Inside each \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"TEST_CASE\"), \" scope, you should follow the \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"AAA\"), \" structure, \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"Arranging\"), \" the data first - both inputs and expected outputs - then \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"Acting\"), \" by calling the function you're testing, then \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"Asserting\"), \" that the results match the expected outputs. We'll make an example for the following toy utility function:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"int add(int a, int b) {\\n    return a + b;\\n}\\n\")), mdx(\"p\", null, \"To test it, we'll need pairs of inputs and their expected outputs. Usually, if there's a lot of data, we'll want to keep it separate from the test logic, but for this example we'll keep it local. Also note that for utilities like this one, we would want a much more comprehensive set of test cases.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"using utility::math::add;\\n\\nTEST_CASE(\\\"Testing integer add utility\\\", \\\"[utility][math][add]\\\") {\\n    // Arrange\\n    static constexpr int NUM_TESTS = 5;\\n    std::array<std::pair<int, int>, NUM_TESTS> inputs = {{0, 0}, {1, 1}, {-1, -1}, {123000, 456}, {-1000, 1000}};\\n    std::array<int, NUM_TESTS> expected_outputs = {0, 2, -2, 123456, 0};\\n    std::array<int, NUM_TESTS> actual_outputs{};\\n    // Act\\n    for (int i = 0; i < NUM_TESTS; ++i) {\\n        actual_outputs[i] = add(inputs[i].first, inputs[i].second);\\n    }\\n    // Assert\\n    for (int i = 0; i < NUM_TESTS; ++i) {\\n        INFO(\\\"In test case number \\\" << i);\\n        INFO(\\\"Inputs are (\\\" << inputs[i].first << \\\", \\\" << inputs[i].second << \\\")\\\");\\n        INFO(\\\"Expected output is \\\" << expected_outputs[i]);\\n        INFO(\\\"Actual output is \\\" << actual_outputs[i]);\\n        REQUIRE(actual_outputs[i] == expected_outputs[i]);\\n    }\\n}\\n\")), mdx(\"h4\", {\n    \"id\": \"dissecting-the-example\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h4\",\n    \"href\": \"#dissecting-the-example\",\n    \"aria-label\": \"dissecting the example permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Dissecting the Example\"), mdx(\"p\", null, \"As we can see in this example, inside the scope of the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"TEST_CASE\"), \" is where it all happens. We use \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"INFO\"), \" macros to annotate exactly what is happening for each assertion. You shouldn't worry too much about creating huge, unwieldy logs with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"INFO\"), \" macros, because by default Catch only prints the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"INFO\"), \" for test cases which fail.\"), mdx(\"p\", null, \"The first argument for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"TEST_CASE\"), \" is a string which is a name for the test. You can use the names to run the specific test. They should be specific. The second argument is a set of tags, which you can use to divide the tests into groups easily. We usually use each sub-namespace the function is located in as the tags. The Catch \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"TEST_CASE\"), \" has much more functionality than demonstrated here and you can find the documentation with the details \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/catchorg/Catch2/blob/devel/docs/test-cases-and-sections.md\"\n  }, \"here\"), \".\"), mdx(\"p\", null, \"The rest of the example is just going through the \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"AAA\"), \" process (the comments are for illustrative purposes). When writing tests we recommend following the Arrange-Act-Assert pattern: first Arrange the data, then Act by calling the code under test, and finally Assert the expected results.\"), mdx(\"h3\", {\n    \"id\": \"catch-bdd-style-tests\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#catch-bdd-style-tests\",\n    \"aria-label\": \"catch bdd style tests permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Catch BDD-style Tests\"), mdx(\"p\", null, \"Catch also supports a Behavior-Driven Development (BDD) style using the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"SCENARIO\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"GIVEN\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"WHEN\"), \", and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"THEN\"), \" macros. BDD-style tests read like specifications and are especially useful for describing behaviours or feature-level scenarios. Use BDD when you want tests to be easily readable by both engineers and non-engineers, or when you are encoding acceptance-style examples.\"), mdx(\"p\", null, \"Example (equivalent behaviour to the basic \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"add\"), \" example, expressed in BDD style):\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-cpp\"\n  }, \"using utility::math::add;\\n\\nSCENARIO(\\\"Adding integers behaves correctly\\\", \\\"[utility][math][add]\\\") {\\n    GIVEN(\\\"Two integers\\\") {\\n        WHEN(\\\"they are small and positive\\\") {\\n            int a = 1;\\n            int b = 1;\\n            THEN(\\\"the sum is their arithmetic sum\\\") {\\n                REQUIRE(add(a, b) == 2);\\n            }\\n        }\\n\\n        WHEN(\\\"they include negative values\\\") {\\n            int a = -1;\\n            int b = -1;\\n            THEN(\\\"they add correctly\\\") {\\n                REQUIRE(add(a, b) == -2);\\n            }\\n        }\\n\\n        WHEN(\\\"they are large but within expected range\\\") {\\n            int a = 123000;\\n            int b = 456;\\n            THEN(\\\"the sum is computed correctly\\\") {\\n                REQUIRE(add(a, b) == 123456);\\n            }\\n        }\\n    }\\n}\\n\")), mdx(\"p\", null, \"Notes on using BDD-style tests:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Use \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"SCENARIO\"), \" to describe the behaviour being specified, and \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"GIVEN\"), \"/\", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"WHEN\"), \"/\", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"THEN\"), \" to structure the example. \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"AND_WHEN\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"AND_THEN\"), \" exist for clearer flow where needed.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Prefer BDD for behavioural or acceptance-style tests that benefit from readable narratives. For very small, focused unit tests the traditional \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"TEST_CASE\"), \" + AAA pattern remains compact and appropriate.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Tags work the same way as with \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"TEST_CASE\"), \" and are useful for grouping or selecting scenarios to run.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"INFO\"), \", \", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"REQUIRE\"), \", and other assertion/diagnostic macros behave the same inside BDD blocks.\")), mdx(\"h3\", {\n    \"id\": \"floating-point-considerations\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#floating-point-considerations\",\n    \"aria-label\": \"floating point considerations permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Floating Point Considerations\"), mdx(\"p\", null, \"Floating point arithmetic is imprecise by nature. Equality comparisons between distinct non-zero floating point numbers are assumed to be false because of this imprecision. Catch has features to deal with the errors from floating point operations. We recommend that if you're testing functions which compute floating point numbers that you \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://github.com/catchorg/Catch2/blob/devel/docs/assertions.md#floating-point-comparisons\"\n  }, \"read about those features\"), \".\"), mdx(\"p\", null, \"You'll need to define a margin of error \\u2014 either relative or absolute \\u2014 that you can tolerate and use that to define your \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Approx\"), \" for each floating point \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"REQUIRE\"), \" assertion.\"), mdx(\"h3\", {\n    \"id\": \"conclusions\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h3\",\n    \"href\": \"#conclusions\",\n    \"aria-label\": \"conclusions permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Conclusions\"), mdx(\"p\", null, \"Catch is concise and powerful. It has many more features than the basic example presented here \\u2014 this is just enough to get you started. Now go and write some tests!\"));\n}\n;\nMDXContent.isMDXComponent = true;","tableOfContents":{"items":[{"url":"#writing-tests","title":"Writing Tests","items":[{"url":"#what-is-a-unit-test","title":"What is a Unit Test?"},{"url":"#anatomy-of-a-unit-test","title":"Anatomy of a Unit Test"},{"url":"#testing-approach-and-philosophy","title":"Testing Approach and Philosophy"},{"url":"#general-approach","title":"General Approach"},{"url":"#regression-tests","title":"Regression Tests"},{"url":"#black-box-vs-white-box-testing","title":"Black Box vs White Box Testing"},{"url":"#tdd-and-bdd","title":"TDD and BDD"}]},{"url":"#catch","title":"Catch","items":[{"url":"#a-basic-example","title":"A Basic Example"},{"url":"#catch-bdd-style-tests","title":"Catch BDD-style Tests"},{"url":"#floating-point-considerations","title":"Floating Point Considerations"},{"url":"#conclusions","title":"Conclusions"}]}]},"frontmatter":{"section":"Guides","chapter":"Main Codebase","title":"Testing and Catch","description":"How to write automated tests, with Catch examples in C++.","keywords":null,"slug":"/guides/testing-and-catch","hidden":null},"childNUbookContributions":{"authors":[],"lastCommit":{"date":"2026-05-28T11:51:27.000Z","hash":"27f12c73e5342904d5606a0d52a0846be74b12a6"}}}},"pageContext":{"mdxPath":"src/book/03-guides/01-main-codebase/06-testing-and-catch.mdx","id":"8c817822-88b1-532c-9c6b-1f07e637b0d3","next":{"chapter":"Main Codebase","title":"Data Recording and Playback","description":"How to record data from a running system and play it back.","slug":"/guides/main/data-recording-playback","hidden":null},"previous":{"chapter":"Main Codebase","title":"Maintaining Subsystems","description":"How to maintain subsystems within the main codebase.","slug":"/guides/main/maintaining-subsystems","hidden":null},"menu":[{"title":"Team","slug":"/team/introduction","chapters":[{"title":"Introduction","slug":"/team/introduction","pages":[{"title":"Introduction to NUbots","slug":"/team/introduction","hidden":null},{"title":"Areas of Research","slug":"/team/areas-of-research","hidden":null},{"title":"Current Team","slug":"/team/current-members","hidden":null}],"hidden":false},{"title":"Joining the Team","slug":"/team/how-we-work","pages":[{"title":"How We Work","slug":"/team/how-we-work","hidden":null},{"title":"How to Join NUbots","slug":"/team/how-to-join","hidden":null},{"title":"Lab Induction","slug":"/team/induction","hidden":null}],"hidden":false},{"title":"Community","slug":"/team/sponsors","pages":[{"title":"Sponsors","slug":"/team/sponsors","hidden":null},{"title":"Connect","slug":"/team/connect","hidden":null}],"hidden":false},{"title":"History","slug":"/team/history","pages":[{"title":"Team History","slug":"/team/history","hidden":null},{"title":"Past Members","slug":"/team/past-members","hidden":null},{"title":"Publications","slug":"/team/publications","hidden":null}],"hidden":false},{"title":"RoboCup","slug":"/team/robocup","pages":[{"title":"RoboCup","slug":"/team/robocup","hidden":null},{"title":"Resources","slug":"/team/robocup/resources","hidden":null},{"title":"Debriefs","slug":"/team/robocup/debriefs","hidden":null}],"hidden":false}],"iconSvg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0z\"/><circle opacity=\".3\" cx=\"9\" cy=\"8\" r=\"2\"/><path opacity=\".3\" d=\"M9 15c-2.7 0-5.8 1.29-6 2.01V18h12v-1c-.2-.71-3.3-2-6-2z\"/><path d=\"M16.67 13.13C18.04 14.06 19 15.32 19 17v3h4v-3c0-2.18-3.57-3.47-6.33-3.87zM15 12c2.21 0 4-1.79 4-4s-1.79-4-4-4c-.47 0-.91.1-1.33.24a5.98 5.98 0 010 7.52c.42.14.86.24 1.33.24zM9 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0-6c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zM9 13c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4zm6 5H3v-.99C3.2 16.29 6.3 15 9 15s5.8 1.29 6 2v1z\"/></svg>","hidden":false},{"title":"System","slug":"/system/foundations/overview","chapters":[{"title":"Foundations","slug":"/system/foundations/overview","pages":[{"title":"Overview","slug":"/system/foundations/overview","hidden":null},{"title":"Build System","slug":"/system/foundations/build-system","hidden":null},{"title":"Continuous Integration","slug":"/system/foundations/ci-system","hidden":null},{"title":"NUClear","slug":"/system/foundations/nuclear","hidden":null},{"title":"Mathematics","slug":"/system/foundations/mathematics","hidden":null},{"title":"Configuration and Script System","slug":"/system/foundations/config-script","hidden":null},{"title":"Director","slug":"/system/foundations/director","hidden":null}],"hidden":false},{"title":"Subsystems","slug":"/system/subsystems/input","pages":[{"title":"Input","slug":"/system/subsystems/input","hidden":null},{"title":"Odometry","slug":"/system/subsystems/odometry","hidden":null},{"title":"Localisation","slug":"/system/subsystems/localisation","hidden":null},{"title":"Motion","slug":"/system/subsystems/motion","hidden":null},{"title":"Vision","slug":"/system/subsystems/vision","hidden":null},{"title":"Behaviour","slug":"/system/subsystems/behaviour","hidden":null},{"title":"Logging","slug":"/system/subsystems/logging","hidden":null}],"hidden":false},{"title":"Tools","slug":"/system/tools/nusight","pages":[{"title":"NUsight","slug":"/system/tools/nusight","hidden":null},{"title":"NUbook","slug":"/system/tools/nubook","hidden":null},{"title":"NUpbr","slug":"/system/tools/nupbr","hidden":null},{"title":"NUgan","slug":"/system/tools/nugan","hidden":null},{"title":"System Configuration","slug":"/system/tools/system_configuration","hidden":null},{"title":"NatNet SDK","slug":"/system/tools/natnet_sdk","hidden":null}],"hidden":false},{"title":"Hardware","slug":"/system/hardware/nugus","pages":[{"title":"NUgus Specification","slug":"/system/hardware/nugus","hidden":null}],"hidden":false},{"title":"Modules","slug":"/system/modules/actuation/","pages":[{"title":"Actuation","slug":"/system/modules/actuation/","hidden":null},{"title":"Extension","slug":"/system/modules/extension/","hidden":null},{"title":"Input","slug":"/system/modules/input/","hidden":null},{"title":"Localisation","slug":"/system/modules/localisation/","hidden":null},{"title":"Network","slug":"/system/modules/network/","hidden":null},{"title":"Output","slug":"/system/modules/output/","hidden":null},{"title":"Planning","slug":"/system/modules/planning/","hidden":null},{"title":"Platform","slug":"/system/modules/platform/","hidden":null},{"title":"Purpose","slug":"/system/modules/purpose/","hidden":null},{"title":"Skill","slug":"/system/modules/skill/","hidden":null},{"title":"Strategy","slug":"/system/modules/strategy/","hidden":null},{"title":"Support","slug":"/system/modules/support/","hidden":null},{"title":"Tools","slug":"/system/modules/tools/","hidden":null},{"title":"Vision","slug":"/system/modules/vision/","hidden":null}],"hidden":false}],"iconSvg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0zm0 0h24v24H0V0z\"/><path opacity=\".3\" d=\"M4 19h14V5H4v14zm8-12h4v3h-4V7zm0 4h4v6h-4v-6zM6 7h5v5H6V7zm0 6h5v4H6v-4z\"/><path d=\"M6 13h5v4H6zm0-6h5v5H6zm6 0h4v3h-4zm0 4h4v6h-4zm10-2V7h-2V5c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-2h2v-2h-2v-2h2v-2h-2V9h2zm-4 10H4V5h14v14z\"/></svg>","hidden":false},{"title":"Guides","slug":"/guides/main/getting-started","chapters":[{"title":"Main Codebase","slug":"/guides/main/getting-started","pages":[{"title":"Getting Started","slug":"/guides/main/getting-started","hidden":null},{"title":"NUClear","slug":"/guides/main/nuclear-tutorial","hidden":null},{"title":"Onboarding Workshop","slug":"/guides/main/onboarding","hidden":null},{"title":"Running and Tuning Scripts","slug":"/guides/main/tuning-and-running-scripts","hidden":null},{"title":"Maintaining Subsystems","slug":"/guides/main/maintaining-subsystems","hidden":null},{"title":"Testing and Catch","slug":"/guides/testing-and-catch","hidden":null},{"title":"Data Recording and Playback","slug":"/guides/main/data-recording-playback","hidden":null},{"title":"Camera Calibration","slug":"/guides/main/camera-calibration","hidden":null}],"hidden":false},{"title":"Tools","slug":"/guides/tools/nusight-contribution","pages":[{"title":"Contributing to NUsight","slug":"/guides/tools/nusight-contribution","hidden":null},{"title":"Setting Up Webots","slug":"/guides/tools/webots-setup","hidden":null},{"title":"Visual Mesh Getting Started","slug":"/guides/tools/visualmesh","hidden":null},{"title":"Using NUpbr","slug":"/guides/tools/nupbr-guide","hidden":null},{"title":"GameController Setup","slug":"/guides/tools/gamecontroller","hidden":null}],"hidden":false},{"title":"Hardware","slug":"/guides/hardware/working-with-robots","pages":[{"title":"Working with Robots","slug":"/guides/hardware/working-with-robots","hidden":null},{"title":"Flashing a Robot","slug":"/guides/hardware/flashing","hidden":null},{"title":"Servo Setup and Calibration","slug":"/guides/hardware/servo-calibration","hidden":null},{"title":"Batteries","slug":"/guides/hardware/batteries","hidden":null},{"title":"DARwIn Op2 Robot Restoration and Calibration Guide","slug":"/guides/hardware/darwin-op2-guide","hidden":null}],"hidden":false},{"title":"General","slug":"/guides/general/learning-resources","pages":[{"title":"Learning Resources","slug":"/guides/general/learning-resources","hidden":null},{"title":"Contribution Workflow","slug":"/guides/general/contribute","hidden":null},{"title":"RoboCup Setup","slug":"/guides/general/robocup-setup","hidden":null},{"title":"Troubleshooting","slug":"/guides/general/troubleshooting","hidden":null},{"title":"Code Conventions","slug":"/guides/general/code-conventions","hidden":null},{"title":"Glossary","slug":"/guides/general/glossary","hidden":null}],"hidden":false}],"iconSvg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0z\"/><path d=\"M21 5c-1.11-.35-2.33-.5-3.5-.5-1.95 0-4.05.4-5.5 1.5-1.45-1.1-3.55-1.5-5.5-1.5S2.45 4.9 1 6v14.65c0 .25.25.5.5.5.1 0 .15-.05.25-.05C3.1 20.45 5.05 20 6.5 20c1.95 0 4.05.4 5.5 1.5 1.35-.85 3.8-1.5 5.5-1.5 1.65 0 3.35.3 4.75 1.05.1.05.15.05.25.05.25 0 .5-.25.5-.5V6c-.6-.45-1.25-.75-2-1zM3 18.5V7c1.1-.35 2.3-.5 3.5-.5 1.34 0 3.13.41 4.5.99v11.5C9.63 18.41 7.84 18 6.5 18c-1.2 0-2.4.15-3.5.5zm18 0c-1.1-.35-2.3-.5-3.5-.5-1.34 0-3.13.41-4.5.99V7.49c1.37-.59 3.16-.99 4.5-.99 1.2 0 2.4.15 3.5.5v11.5z\"/><path opacity=\".3\" d=\"M11 7.49c-1.37-.58-3.16-.99-4.5-.99-1.2 0-2.4.15-3.5.5v11.5c1.1-.35 2.3-.5 3.5-.5 1.34 0 3.13.41 4.5.99V7.49z\"/><g><path d=\"M17.5 10.5c.88 0 1.73.09 2.5.26V9.24c-.79-.15-1.64-.24-2.5-.24-1.28 0-2.46.16-3.5.47v1.57c.99-.35 2.18-.54 3.5-.54zM17.5 13.16c.88 0 1.73.09 2.5.26V11.9c-.79-.15-1.64-.24-2.5-.24-1.28 0-2.46.16-3.5.47v1.57c.99-.34 2.18-.54 3.5-.54zM17.5 15.83c.88 0 1.73.09 2.5.26v-1.52c-.79-.15-1.64-.24-2.5-.24-1.28 0-2.46.16-3.5.47v1.57c.99-.35 2.18-.54 3.5-.54z\"/></g></svg>","hidden":false},{"title":"Kitchen Sink","slug":"/kitchen-sink/headers","chapters":[{"title":"Markdown","slug":"/kitchen-sink/headers","pages":[{"title":"Headers","slug":"/kitchen-sink/headers","hidden":true},{"title":"Formatting and Paragraphs","slug":"/kitchen-sink/formatting-and-paragraphs","hidden":true},{"title":"Blockquotes","slug":"/kitchen-sink/blockquotes","hidden":true},{"title":"Alerts","slug":"/kitchen-sink/alerts","hidden":true},{"title":"Images","slug":"/kitchen-sink/images","hidden":true},{"title":"Lists","slug":"/kitchen-sink/lists","hidden":true},{"title":"Code","slug":"/kitchen-sink/code","hidden":true},{"title":"Math","slug":"/kitchen-sink/math","hidden":true},{"title":"Table of Contents","slug":"/kitchen-sink/table-of-contents","hidden":true},{"title":"Tables","slug":"/kitchen-sink/tables","hidden":true},{"title":"Collapsible Content","slug":"/kitchen-sink/collapsible","hidden":true},{"title":"GraphViz Diagrams","slug":"/kitchen-sink/graphviz-diagrams","hidden":true},{"title":"Referencing","slug":"/kitchen-sink/referencing","hidden":true}],"hidden":true}],"iconSvg":"<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\"><g><rect fill=\"none\" height=\"24\" width=\"24\"/></g><g><g><g opacity=\".3\"><polygon points=\"8.66,14.64 4.41,18.88 5.12,19.59 9.36,15.34 9.36,15.34 8.66,14.64\"/></g><g opacity=\".3\"><rect height=\"6\" transform=\"matrix(0.7071 -0.7071 0.7071 0.7071 -7.0983 17.0848)\" width=\"1\" x=\"16.57\" y=\"14.11\"/></g><g><path d=\"M21.67,18.17l-5.3-5.3h-0.99l-2.54,2.54v0.99l5.3,5.3c0.39,0.39,1.02,0.39,1.41,0l2.12-2.12 C22.06,19.2,22.06,18.56,21.67,18.17z M18.84,19.59l-4.24-4.24l0.71-0.71l4.24,4.24L18.84,19.59z\"/></g><g><path d=\"M17.34,10.19l1.41-1.41l2.12,2.12c1.17-1.17,1.17-3.07,0-4.24l-3.54-3.54l-1.41,1.41V1.71L15.22,1l-3.54,3.54l0.71,0.71 h2.83l-1.41,1.41l1.06,1.06l-2.89,2.89L7.85,6.48V5.06L4.83,2.04L2,4.87l3.03,3.03h1.41l4.13,4.13l-0.85,0.85H7.6l-5.3,5.3 c-0.39,0.39-0.39,1.02,0,1.41l2.12,2.12c0.39,0.39,1.02,0.39,1.41,0l5.3-5.3v-2.12l5.15-5.15L17.34,10.19z M9.36,15.34 l-4.24,4.24l-0.71-0.71l4.24-4.24l0,0L9.36,15.34L9.36,15.34z\"/></g></g></g></svg>","hidden":true}],"references":null,"hidden":null}},
    "staticQueryHashes": ["2362849146","445096115","962821121"]}