Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
micro_test.h
00001 /* Copyright 2018 The TensorFlow Authors. All Rights Reserved. 00002 00003 Licensed under the Apache License, Version 2.0 (the "License"); 00004 you may not use this file except in compliance with the License. 00005 You may obtain a copy of the License at 00006 00007 http://www.apache.org/licenses/LICENSE-2.0 00008 00009 Unless required by applicable law or agreed to in writing, software 00010 distributed under the License is distributed on an "AS IS" BASIS, 00011 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 See the License for the specific language governing permissions and 00013 limitations under the License. 00014 ==============================================================================*/ 00015 00016 // An ultra-lightweight testing framework designed for use with microcontroller 00017 // applications. Its only dependency is on TensorFlow Lite's ErrorReporter 00018 // interface, where log messages are output. This is designed to be usable even 00019 // when no standard C or C++ libraries are available, and without any dynamic 00020 // memory allocation or reliance on global constructors. 00021 // 00022 // To build a test, you use syntax similar to gunit, but with some extra 00023 // decoration to create a hidden 'main' function containing each of the tests to 00024 // be run. Your code should look something like: 00025 // ---------------------------------------------------------------------------- 00026 // #include "path/to/this/header" 00027 // 00028 // TF_LITE_MICRO_TESTS_BEGIN 00029 // 00030 // TF_LITE_MICRO_TEST(SomeTest) { 00031 // TF_LITE_LOG_EXPECT_EQ(true, true); 00032 // } 00033 // 00034 // TF_LITE_MICRO_TESTS_END 00035 // ---------------------------------------------------------------------------- 00036 // If you compile this for your platform, you'll get a normal binary that you 00037 // should be able to run. Executing it will output logging information like this 00038 // to stderr (or whatever equivalent is available and written to by 00039 // ErrorReporter): 00040 // ---------------------------------------------------------------------------- 00041 // Testing SomeTest 00042 // 1/1 tests passed 00043 // ~~~ALL TESTS PASSED~~~ 00044 // ---------------------------------------------------------------------------- 00045 // This is designed to be human-readable, so you can just run tests manually, 00046 // but the string "~~~ALL TESTS PASSED~~~" should only appear if all of the 00047 // tests do pass. This makes it possible to integrate with automated test 00048 // systems by scanning the output logs and looking for that magic value. 00049 // 00050 // This framework is intended to be a rudimentary alternative to no testing at 00051 // all on systems that struggle to run more conventional approaches, so use with 00052 // caution! 00053 00054 #ifndef TENSORFLOW_LITE_EXPERIMENTAL_MICRO_TESTING_MICRO_TEST_H_ 00055 #define TENSORFLOW_LITE_EXPERIMENTAL_MICRO_TESTING_MICRO_TEST_H_ 00056 00057 #include "tensorflow/lite/experimental/micro/micro_error_reporter.h" 00058 00059 namespace micro_test { 00060 extern int tests_passed; 00061 extern int tests_failed; 00062 extern bool is_test_complete; 00063 extern bool did_test_fail; 00064 extern tflite::ErrorReporter* reporter; 00065 } // namespace micro_test 00066 00067 #define TF_LITE_MICRO_TESTS_BEGIN \ 00068 namespace micro_test { \ 00069 int tests_passed; \ 00070 int tests_failed; \ 00071 bool is_test_complete; \ 00072 bool did_test_fail; \ 00073 tflite::ErrorReporter* reporter; \ 00074 } \ 00075 \ 00076 int main(int argc, char** argv) { \ 00077 micro_test::tests_passed = 0; \ 00078 micro_test::tests_failed = 0; \ 00079 tflite::MicroErrorReporter error_reporter; \ 00080 micro_test::reporter = &error_reporter; 00081 00082 #define TF_LITE_MICRO_TESTS_END \ 00083 micro_test::reporter->Report( \ 00084 "%d/%d tests passed", micro_test::tests_passed, \ 00085 (micro_test::tests_failed + micro_test::tests_passed)); \ 00086 if (micro_test::tests_failed == 0) { \ 00087 micro_test::reporter->Report("~~~ALL TESTS PASSED~~~\n"); \ 00088 } else { \ 00089 micro_test::reporter->Report("~~~SOME TESTS FAILED~~~\n"); \ 00090 } \ 00091 } 00092 00093 // TODO(petewarden): I'm going to hell for what I'm doing to this poor for loop. 00094 #define TF_LITE_MICRO_TEST(name) \ 00095 micro_test::reporter->Report("Testing %s", #name); \ 00096 for (micro_test::is_test_complete = false, \ 00097 micro_test::did_test_fail = false; \ 00098 !micro_test::is_test_complete; micro_test::is_test_complete = true, \ 00099 micro_test::tests_passed += (micro_test::did_test_fail) ? 0 : 1, \ 00100 micro_test::tests_failed += (micro_test::did_test_fail) ? 1 : 0) 00101 00102 #define TF_LITE_MICRO_EXPECT(x) \ 00103 do { \ 00104 if (!(x)) { \ 00105 micro_test::reporter->Report(#x " failed at %s:%d", __FILE__, __LINE__); \ 00106 micro_test::did_test_fail = true; \ 00107 } \ 00108 } while (false) 00109 00110 #define TF_LITE_MICRO_EXPECT_EQ(x, y) \ 00111 do { \ 00112 if ((x) != (y)) { \ 00113 micro_test::reporter->Report(#x " == " #y " failed at %s:%d (%d vs %d)", \ 00114 __FILE__, __LINE__, (x), (y)); \ 00115 micro_test::did_test_fail = true; \ 00116 } \ 00117 } while (false) 00118 00119 #define TF_LITE_MICRO_EXPECT_NE(x, y) \ 00120 do { \ 00121 if ((x) == (y)) { \ 00122 micro_test::reporter->Report(#x " != " #y " failed at %s:%d", __FILE__, \ 00123 __LINE__); \ 00124 micro_test::did_test_fail = true; \ 00125 } \ 00126 } while (false) 00127 00128 // TODO(wangtz): Making it more generic once needed. 00129 #define TF_LITE_MICRO_ARRAY_ELEMENT_EXPECT_NEAR(arr1, idx1, arr2, idx2, \ 00130 epsilon) \ 00131 do { \ 00132 auto delta = ((arr1)[(idx1)] > (arr2)[(idx2)]) \ 00133 ? ((arr1)[(idx1)] - (arr2)[(idx2)]) \ 00134 : ((arr2)[(idx2)] - (arr1)[(idx1)]); \ 00135 if (delta > epsilon) { \ 00136 micro_test::reporter->Report( \ 00137 #arr1 "[%d] (%f) near " #arr2 "[%d] (%f) failed at %s:%d", \ 00138 static_cast<int>(idx1), static_cast<float>((arr1)[(idx1)]), \ 00139 static_cast<int>(idx2), static_cast<float>((arr2)[(idx2)]), \ 00140 __FILE__, __LINE__); \ 00141 micro_test::did_test_fail = true; \ 00142 } \ 00143 } while (false) 00144 00145 #define TF_LITE_MICRO_EXPECT_NEAR(x, y, epsilon) \ 00146 do { \ 00147 auto delta = ((x) > (y)) ? ((x) - (y)) : ((y) - (x)); \ 00148 if (delta > epsilon) { \ 00149 micro_test::reporter->Report( \ 00150 #x " (%f) near " #y " (%f) failed at %s:%d", static_cast<float>(x), \ 00151 static_cast<float>(y), __FILE__, __LINE__); \ 00152 micro_test::did_test_fail = true; \ 00153 } \ 00154 } while (false) 00155 00156 #define TF_LITE_MICRO_EXPECT_GT(x, y) \ 00157 do { \ 00158 if ((x) <= (y)) { \ 00159 micro_test::reporter->Report(#x " > " #y " failed at %s:%d", __FILE__, \ 00160 __LINE__); \ 00161 micro_test::did_test_fail = true; \ 00162 } \ 00163 } while (false) 00164 00165 #define TF_LITE_MICRO_EXPECT_LT(x, y) \ 00166 do { \ 00167 if ((x) >= (y)) { \ 00168 micro_test::reporter->Report(#x " < " #y " failed at %s:%d", __FILE__, \ 00169 __LINE__); \ 00170 micro_test::did_test_fail = true; \ 00171 } \ 00172 } while (false) 00173 00174 #define TF_LITE_MICRO_EXPECT_GE(x, y) \ 00175 do { \ 00176 if ((x) < (y)) { \ 00177 micro_test::reporter->Report(#x " >= " #y " failed at %s:%d", __FILE__, \ 00178 __LINE__); \ 00179 micro_test::did_test_fail = true; \ 00180 } \ 00181 } while (false) 00182 00183 #define TF_LITE_MICRO_EXPECT_LE(x, y) \ 00184 do { \ 00185 if ((x) > (y)) { \ 00186 micro_test::reporter->Report(#x " <= " #y " failed at %s:%d", __FILE__, \ 00187 __LINE__); \ 00188 micro_test::did_test_fail = true; \ 00189 } \ 00190 } while (false) 00191 00192 #define TF_LITE_MICRO_EXPECT_TRUE(x) \ 00193 do { \ 00194 if (!x) { \ 00195 micro_test::reporter->Report(#x " was not true failed at %s:%d", \ 00196 __FILE__, __LINE__); \ 00197 micro_test::did_test_fail = true; \ 00198 } \ 00199 } while (false) 00200 00201 #define TF_LITE_MICRO_EXPECT_FALSE(x) \ 00202 do { \ 00203 if (x) { \ 00204 micro_test::reporter->Report(#x " was not false failed at %s:%d", \ 00205 __FILE__, __LINE__); \ 00206 micro_test::did_test_fail = true; \ 00207 } \ 00208 } while (false) 00209 00210 #endif // TENSORFLOW_LITE_EXPERIMENTAL_MICRO_TESTING_MICRO_TEST_H_
Generated on Wed Jul 13 2022 16:03:35 by
1.7.2