diff --git a/integration-tests/tests/code_checkers.rs b/integration-tests/tests/code_checkers.rs
new file mode 100644
index 0000000..619c79c
--- /dev/null
+++ b/integration-tests/tests/code_checkers.rs
@@ -0,0 +1,182 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::{
+    fs::File,
+    io::{BufRead, BufReader},
+    path::PathBuf,
+};
+
+use itertools::{Either, Itertools};
+use proc_macro2::TokenStream;
+use quote::ToTokens;
+use syn::Item;
+
+use autocxx_integration_tests::{CodeChecker, CodeCheckerFns, TestError};
+
+/// Generates a closure which can be used to ensure that the given symbol
+/// is mentioned in the output and has documentation attached.
+/// The idea is that this is what we do in cases where we can't generate code properly.
+pub(crate) fn make_error_finder(error_symbol: &'static str) -> CodeChecker {
+    Box::new(ErrorFinder(error_symbol))
+}
+struct ErrorFinder(&'static str);
+
+impl CodeCheckerFns for ErrorFinder {
+    fn check_rust(&self, rs: syn::File) -> Result<(), TestError> {
+        let ffi_items = find_ffi_items(rs)?;
+        // Ensure there's some kind of struct entry for this symbol
+        let error_item = ffi_items
+            .into_iter()
+            .filter_map(|i| match i {
+                Item::Struct(its) if its.ident == self.0 => Some(its),
+                _ => None,
+            })
+            .next()
+            .ok_or_else(|| TestError::RsCodeExaminationFail("Couldn't find item".into()))?;
+        // Ensure doc attribute
+        error_item
+            .attrs
+            .into_iter()
+            .find(|a| a.path.get_ident().filter(|p| *p == "doc").is_some())
+            .ok_or_else(|| TestError::RsCodeExaminationFail("Item had no docs".into()))?;
+        Ok(())
+    }
+}
+
+fn find_ffi_items(f: syn::File) -> Result<Vec<Item>, TestError> {
+    let md = f
+        .items
+        .into_iter()
+        .filter_map(|i| match i {
+            Item::Mod(itm) => Some(itm),
+            _ => None,
+        })
+        .next()
+        .ok_or_else(|| TestError::RsCodeExaminationFail("No mods in file".into()))?;
+    let mut items = Vec::new();
+    find_all_non_mod_items(md, &mut items);
+    Ok(items)
+}
+
+fn find_all_non_mod_items(md: syn::ItemMod, items: &mut Vec<Item>) {
+    let (more_mods, mut these_items): (Vec<_>, Vec<_>) = md
+        .content
+        .into_iter()
+        .flat_map(|(_, more_items)| more_items.into_iter())
+        .partition_map(|i| match i {
+            Item::Mod(itm) => Either::Left(itm),
+            _ => Either::Right(i),
+        });
+    items.append(&mut these_items);
+    for md in more_mods.into_iter() {
+        find_all_non_mod_items(md, items);
+    }
+}
+
+struct StringFinder(Vec<String>);
+
+impl CodeCheckerFns for StringFinder {
+    fn check_rust(&self, rs: syn::File) -> Result<(), TestError> {
+        let toks = rs.to_token_stream().to_string();
+        for msg in &self.0 {
+            if !toks.contains(msg) {
+                return Err(TestError::RsCodeExaminationFail(format!(
+                    "Couldn't find string '{}'",
+                    msg
+                )));
+            };
+        }
+        Ok(())
+    }
+}
+
+/// Returns a code checker which simply hunts for a given string in the results
+pub(crate) fn make_string_finder(error_texts: Vec<String>) -> CodeChecker {
+    Box::new(StringFinder(error_texts))
+}
+
+struct RustCodeFinder(Vec<TokenStream>);
+
+impl CodeCheckerFns for RustCodeFinder {
+    fn check_rust(&self, rs: syn::File) -> Result<(), TestError> {
+        let haystack = rs.to_token_stream().to_string();
+        for msg in &self.0 {
+            let needle = msg.to_string();
+            if !haystack.contains(&needle) {
+                return Err(TestError::RsCodeExaminationFail(format!(
+                    "Couldn't find tokens '{}'",
+                    needle
+                )));
+            };
+        }
+        Ok(())
+    }
+}
+
+/// Returns a code checker which hunts for the given Rust tokens in the output
+pub(crate) fn make_rust_code_finder(code: Vec<TokenStream>) -> CodeChecker {
+    Box::new(RustCodeFinder(code))
+}
+
+/// Searches generated C++ for strings we want to find, or want _not_ to find,
+/// or both.
+pub(crate) struct CppMatcher<'a> {
+    positive_matches: &'a [&'a str],
+    negative_matches: &'a [&'a str],
+}
+
+impl<'a> CppMatcher<'a> {
+    pub(crate) fn new(positive_matches: &'a [&'a str], negative_matches: &'a [&'a str]) -> Self {
+        Self {
+            positive_matches,
+            negative_matches,
+        }
+    }
+}
+
+impl<'a> CodeCheckerFns for CppMatcher<'a> {
+    fn check_cpp(&self, cpp: &[PathBuf]) -> Result<(), TestError> {
+        let mut positives_needed = self.positive_matches.to_vec();
+        for filename in cpp {
+            let file = File::open(filename).unwrap();
+            let lines = BufReader::new(file).lines();
+            for l in lines.filter_map(|l| l.ok()) {
+                if self.negative_matches.iter().any(|neg| l.contains(neg)) {
+                    return Err(TestError::CppCodeExaminationFail);
+                }
+                positives_needed.retain(|pos| !l.contains(pos));
+            }
+        }
+        if positives_needed.is_empty() {
+            Ok(())
+        } else {
+            Err(TestError::CppCodeExaminationFail)
+        }
+    }
+}
+
+pub(crate) struct NoSystemHeadersChecker;
+
+impl CodeCheckerFns for NoSystemHeadersChecker {
+    fn check_cpp(&self, cpp: &[PathBuf]) -> Result<(), TestError> {
+        for filename in cpp {
+            let file = File::open(filename).unwrap();
+            if BufReader::new(file)
+                .lines()
+                .any(|l| l.as_ref().unwrap().starts_with("#include <"))
+            {
+                return Err(TestError::CppCodeExaminationFail);
+            }
+        }
+        Ok(())
+    }
+    fn skip_build(&self) -> bool {
+        true
+    }
+}
