├── .gitignore ├── UnitTest-Library.mqh ├── LICENSE ├── README.md ├── examples └── Examples.mq5 └── src ├── FailedUnitTest.mqh ├── UnitTestsCollection.mqh └── UnitTests.mqh /.gitignore: -------------------------------------------------------------------------------- 1 | *.ex5 -------------------------------------------------------------------------------- /UnitTest-Library.mqh: -------------------------------------------------------------------------------- 1 | //+------------------------------------------------------------------+ 2 | //| MQL5UnitTest.mqh | 3 | //| Copyright 2014, Louis Fradin | 4 | //| http://en.louis-fradin.net/ | 5 | //+------------------------------------------------------------------+ 6 | 7 | #property copyright "Copyright 2014, Louis Fradin" 8 | #property link "http://en.louis-fradin.net/" 9 | #property version "1.00" 10 | 11 | //+------------------------------------------------------------------+ 12 | //| Inclusions 13 | //+------------------------------------------------------------------+ 14 | 15 | #include "src/FailedUnitTest.mqh" 16 | #include "src/UnitTests.mqh" 17 | #include "src/UnitTestsCollection.mqh" 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Louis Fradin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UTLibrary-mql5 2 | Unit Test Library for MQL5 programs. 3 | 4 | ## Use 5 | In your script, create a UnitTestsCollection in order to regroup all unitTests. 6 | 7 | void OnStart(){ 8 | CUnitTestsCollection utCollection(); 9 | 10 | utCollection.AddUnitTests(TestFail()); 11 | utCollection.AddUnitTests(TestSuccess()); 12 | } 13 | 14 | Then, you can regroup unit tests by themes in functions, in order 15 | to add them to the collection. 16 | 17 | CUnitTests* TestSuccess(){ 18 | CUnitTests* ut = new CUnitTests("TestSuccess"); 19 | 20 | ut.IsFalse(__FILE__, __LINE__, false); 21 | ... 22 | ut.IsEquals(__FILE__, __LINE__, "Bonjour", "Bonjour"); 23 | 24 | return ut; 25 | } 26 | 27 | For more informations, see examples. 28 | 29 | ## Available tests 30 | 31 | * Booleans 32 | * bool **IsTrue**(string file, int line, bool result); 33 | * bool **IsFalse**(string file, int line, bool result); 34 | * Strings 35 | * bool **IsEquals**(string file, int line, string stringA, string stringB); 36 | * bool **IsNotEquals**(string file, int line, double nbrA, double nbrB); 37 | * Integers 38 | * bool **IsEquals**(string file, int line, int nbrA, int nbrB); 39 | * Doubles 40 | * bool **IsEquals**(string file, int line, double nbrA, double nbrB); 41 | * bool **IsNotEquals**(string file, int line, double nbrA, double nbrB); 42 | * Others 43 | * void **SetFalse**(string file, int line, string message); 44 | 45 | ## Ameliorations 46 | I will add tests when I need them. Feel free to propose yours. 47 | -------------------------------------------------------------------------------- /examples/Examples.mq5: -------------------------------------------------------------------------------- 1 | //+------------------------------------------------------------------+ 2 | //| Examples.mq5 | 3 | //| Copyright 2015, Louis Fradin | 4 | //| http://en.louis-fradin.net/ | 5 | //+------------------------------------------------------------------+ 6 | 7 | #property copyright "Copyright 2015, Louis Fradin" 8 | #property link "http://en.louis-fradin.net/" 9 | #property version "1.00" 10 | 11 | #include "../UnitTest-Library.mqh" 12 | 13 | //+------------------------------------------------------------------+ 14 | //| Script program start function | 15 | //+------------------------------------------------------------------+ 16 | 17 | void OnStart(){ 18 | CUnitTestsCollection utCollection(); 19 | 20 | utCollection.AddUnitTests(TestFail()); 21 | utCollection.AddUnitTests(TestSuccess()); 22 | } 23 | 24 | //+------------------------------------------------------------------+ 25 | //| Failed Unit Tests 26 | //+------------------------------------------------------------------+ 27 | 28 | CUnitTests* TestFail(){ 29 | CUnitTests* ut = new CUnitTests("TestFail"); 30 | 31 | // Verification of a true 32 | ut.IsFalse(__FILE__, __LINE__, true); 33 | ut.IsTrue(__FILE__, __LINE__, false); 34 | ut.IsEquals(__FILE__, __LINE__, "Bonjour", "bonjour"); 35 | 36 | return ut; 37 | } 38 | 39 | //+------------------------------------------------------------------+ 40 | //| Test of the false 41 | //+------------------------------------------------------------------+ 42 | 43 | CUnitTests* TestSuccess(){ 44 | CUnitTests* ut = new CUnitTests("TestSuccess"); 45 | 46 | // Verification of a true 47 | ut.IsFalse(__FILE__, __LINE__, false); 48 | ut.IsTrue(__FILE__, __LINE__, true); 49 | ut.IsEquals(__FILE__, __LINE__, "Bonjour", "Bonjour"); 50 | 51 | return ut; 52 | } 53 | 54 | //+------------------------------------------------------------------+ 55 | -------------------------------------------------------------------------------- /src/FailedUnitTest.mqh: -------------------------------------------------------------------------------- 1 | //+------------------------------------------------------------------+ 2 | //| FailedTestClass.mqh | 3 | //| Copyright 2015, Louis Fradin | 4 | //| http://en.louis-fradin.net/ | 5 | //+------------------------------------------------------------------+ 6 | 7 | #property copyright "Copyright 2015, Louis Fradin" 8 | #property link "http://en.louis-fradin.net/" 9 | 10 | #include 11 | 12 | //+------------------------------------------------------------------+ 13 | //| Prototype 14 | //+------------------------------------------------------------------+ 15 | 16 | class CFailedUnitTest: public CObject{ 17 | private: 18 | string m_file; 19 | int m_line; 20 | string m_result; 21 | public: 22 | CFailedUnitTest(string file, int line); 23 | ~CFailedUnitTest(); 24 | 25 | void Display(); 26 | 27 | // Mutators 28 | void SetResult(string text); 29 | 30 | // Accessors 31 | string GetResult(); 32 | }; 33 | 34 | //+------------------------------------------------------------------+ 35 | //| Constructor 36 | //| @param testNumber Number of the test 37 | //+------------------------------------------------------------------+ 38 | 39 | CFailedUnitTest::CFailedUnitTest(string file, int line){ 40 | m_file = file; 41 | m_line = line; 42 | m_result = ""; 43 | } 44 | 45 | //+------------------------------------------------------------------+ 46 | //| Destructor 47 | //+------------------------------------------------------------------+ 48 | 49 | CFailedUnitTest::~CFailedUnitTest(){ 50 | } 51 | 52 | //+------------------------------------------------------------------+ 53 | //| Display the failed test 54 | //+------------------------------------------------------------------+ 55 | 56 | void CFailedUnitTest::Display(){ 57 | Print("+"+m_file+":"+IntegerToString(m_line) 58 | +" : "+m_result); 59 | } 60 | 61 | //+------------------------------------------------------------------+ 62 | //| Set the result text 63 | //| @param text Text resuming what happened 64 | //+------------------------------------------------------------------+ 65 | 66 | void CFailedUnitTest::SetResult(string text){ 67 | m_result = text; 68 | } 69 | 70 | 71 | //+------------------------------------------------------------------+ 72 | //| Return the result 73 | //| @return Text of the result 74 | //+------------------------------------------------------------------+ 75 | 76 | string CFailedUnitTest::GetResult(){ 77 | return m_result; 78 | } 79 | 80 | //+------------------------------------------------------------------+ -------------------------------------------------------------------------------- /src/UnitTestsCollection.mqh: -------------------------------------------------------------------------------- 1 | //+------------------------------------------------------------------+ 2 | //| UnitTestCollectionClass.mqh | 3 | //| Copyright 2015, Louis Fradin | 4 | //| http://en.louis-fradin.net/ | 5 | //+------------------------------------------------------------------+ 6 | 7 | #property copyright "Copyright 2015, Louis Fradin" 8 | #property link "http://en.louis-fradin.net/" 9 | 10 | #include 11 | #include 12 | #include "UnitTests.mqh" 13 | 14 | //+------------------------------------------------------------------+ 15 | //| Prototype 16 | //+------------------------------------------------------------------+ 17 | 18 | class CUnitTestsCollection: public CObject{ 19 | private: 20 | CList m_unitTestsList; 21 | 22 | void DisplayFailedTests(); 23 | public: 24 | void AddUnitTests(CUnitTests *ut); 25 | 26 | CUnitTestsCollection(); 27 | ~CUnitTestsCollection(); 28 | }; 29 | 30 | //+------------------------------------------------------------------+ 31 | //| Constructor 32 | //+------------------------------------------------------------------+ 33 | 34 | CUnitTestsCollection::CUnitTestsCollection(){ 35 | Print(" --- Unit Tests beginning -------------------------------"); 36 | } 37 | 38 | //+------------------------------------------------------------------+ 39 | //| Destructor 40 | //+------------------------------------------------------------------+ 41 | 42 | CUnitTestsCollection::~CUnitTestsCollection(){ 43 | Print(" --- Unit Tests end -------------------------------------"); 44 | DisplayFailedTests(); 45 | 46 | // Clear the list 47 | m_unitTestsList.Clear(); 48 | } 49 | 50 | //+------------------------------------------------------------------+ 51 | //| Display failed test of the unit tests added 52 | //+------------------------------------------------------------------+ 53 | 54 | CUnitTestsCollection::DisplayFailedTests(){ 55 | CFailedUnitTest *failedTest; 56 | CUnitTests *unitTest = m_unitTestsList.GetFirstNode(); 57 | int nbrOfUnitTests = m_unitTestsList.Total(); 58 | int total; 59 | string summary; 60 | 61 | for(int i = 0; i < nbrOfUnitTests; i++){ // For all unit tests 62 | total = unitTest.TotalFailedTests(); 63 | 64 | if(total!=0){ // If there is a failed test 65 | summary += "F "; 66 | Print(unitTest.GetName()+" failed"); 67 | 68 | for(int j = 0; j < total; j++){ 69 | failedTest = unitTest.GetFailedTest(j); 70 | failedTest.Display(); 71 | } 72 | } 73 | else{ 74 | summary += ". "; 75 | Print(unitTest.GetName()+" success"); 76 | } 77 | 78 | unitTest = m_unitTestsList.GetNextNode(); 79 | } 80 | 81 | Print(" --------------------------------------------------------"); 82 | Print(summary); 83 | } 84 | 85 | //+------------------------------------------------------------------+ 86 | //| Add a unit test to the collection 87 | //| @param ut The unit test to add 88 | //+------------------------------------------------------------------+ 89 | 90 | void CUnitTestsCollection::AddUnitTests(CUnitTests *ut){ 91 | m_unitTestsList.Add(ut); 92 | } 93 | 94 | //+------------------------------------------------------------------+ 95 | -------------------------------------------------------------------------------- /src/UnitTests.mqh: -------------------------------------------------------------------------------- 1 | //+------------------------------------------------------------------+ 2 | //| MQL5UnitTest.mqh | 3 | //| Copyright 2014, Louis Fradin | 4 | //| http://en.louis-fradin.net/ | 5 | //+------------------------------------------------------------------+ 6 | 7 | #property copyright "Copyright 2014, Louis Fradin" 8 | #property link "http://en.louis-fradin.net/" 9 | #property version "1.00" 10 | 11 | #include 12 | #include 13 | #include "FailedUnitTest.mqh" 14 | 15 | //+------------------------------------------------------------------+ 16 | //| Prototype 17 | //+------------------------------------------------------------------+ 18 | 19 | class CUnitTests: public CObject{ 20 | private: 21 | string m_name; 22 | CList m_failedTestsList; 23 | 24 | void AddFailedTest(string file, int line, string message); 25 | 26 | public: 27 | CUnitTests(string testName); 28 | ~CUnitTests(); 29 | 30 | // Tests 31 | bool IsTrue(string file, int line, bool result); 32 | bool IsFalse(string file, int line, bool result); 33 | bool IsEquals(string file, int line, string stringA, string stringB); 34 | bool IsEquals(string file, int line, int nbrA, int nbrB); 35 | bool IsEquals(string file, int line, double nbrA, double nbrB); 36 | bool IsNotEquals(string file, int line, double nbrA, double nbrB); 37 | void SetFalse(string file, int line, string message); 38 | 39 | // Failed tests 40 | CFailedUnitTest* GetFailedTest(int position); 41 | int TotalFailedTests(); 42 | 43 | // Accessors 44 | string GetName(); 45 | }; 46 | 47 | //+------------------------------------------------------------------+ 48 | //| Constructor 49 | //+------------------------------------------------------------------+ 50 | 51 | CUnitTests::CUnitTests(string testName){ 52 | m_name = testName; 53 | Print(" => "+m_name); 54 | } 55 | 56 | //+------------------------------------------------------------------+ 57 | //| Destructor 58 | //+------------------------------------------------------------------+ 59 | 60 | CUnitTests::~CUnitTests(){ 61 | m_failedTestsList.Clear(); 62 | } 63 | 64 | //+------------------------------------------------------------------+ 65 | //| Add a Failed Test to the intern list of failed tests 66 | //+------------------------------------------------------------------+ 67 | 68 | void CUnitTests::AddFailedTest(string file, int line, string message){ 69 | CFailedUnitTest *newFailedTest = new CFailedUnitTest(file,line); 70 | 71 | // Add informations 72 | newFailedTest.SetResult(message); 73 | 74 | // Insert the failed Test 75 | m_failedTestsList.Add(newFailedTest); 76 | } 77 | 78 | //+------------------------------------------------------------------+ 79 | //| Unit test verifying if the argument is true 80 | //| @param result Boolean to compare 81 | //+------------------------------------------------------------------+ 82 | 83 | bool CUnitTests::IsTrue(string file, int line, bool result){ 84 | if(result!=true){ 85 | this.AddFailedTest(file, line, "isTrue(False)"); 86 | return false; 87 | } 88 | else 89 | return true; 90 | } 91 | 92 | //+------------------------------------------------------------------+ 93 | //| Unit test verifying if the argument is true 94 | //| @param result Boolean to compare 95 | //+------------------------------------------------------------------+ 96 | 97 | bool CUnitTests::IsFalse(string file, int line, bool result){ 98 | if(result!=false){ 99 | this.AddFailedTest(file, line, "isFalse(True)"); 100 | return false; 101 | } 102 | else 103 | return true; 104 | } 105 | 106 | //+------------------------------------------------------------------+ 107 | //| Unit test verifying if the two string arguments are equals 108 | //| @param stringA First string to compare 109 | //| @param stringB Second string to compare 110 | //+------------------------------------------------------------------+ 111 | 112 | bool CUnitTests::IsEquals(string file, int line, string stringA,string stringB){ 113 | if(stringA!=stringB){ // If strings are differents 114 | string message = "IsEquals('"+stringA+"','"+stringB+"')"; 115 | this.AddFailedTest(file, line, message); // Add a fail test 116 | return false; 117 | } 118 | else 119 | return true; 120 | } 121 | 122 | //+------------------------------------------------------------------+ 123 | //| Unit test verifying if the two int arguments are equals 124 | //| @param nbrA First int to compare 125 | //| @param nbrB Second int to compare 126 | //+------------------------------------------------------------------+ 127 | 128 | bool CUnitTests::IsEquals(string file, int line, int nbrA, int nbrB){ 129 | if(nbrA!=nbrB){ // If strings are differents 130 | string message = "IsEquals("+IntegerToString(nbrA)+","+IntegerToString(nbrB)+")"; 131 | this.AddFailedTest(file, line, message); // Add a fail test 132 | return false; 133 | } 134 | else 135 | return true; 136 | } 137 | 138 | //+------------------------------------------------------------------+ 139 | //| Unit test verifying if the two double arguments are equals 140 | //| @param nbrA First double to compare 141 | //| @param nbrB Second double to compare 142 | //+------------------------------------------------------------------+ 143 | 144 | bool CUnitTests::IsEquals(string file, int line, double nbrA, double nbrB){ 145 | if(nbrA!=nbrB){ // If strings are differents 146 | string message = "IsEquals("+DoubleToString(nbrA)+","+DoubleToString(nbrB)+")"; 147 | this.AddFailedTest(file, line, message); // Add a fail test 148 | return false; 149 | } 150 | else 151 | return true; 152 | } 153 | 154 | //+------------------------------------------------------------------+ 155 | //| Unit test verifying if the two double arguments are not equals 156 | //| @param nbrA First double to compare 157 | //| @param nbrB Second double to compare 158 | //+------------------------------------------------------------------+ 159 | 160 | bool CUnitTests::IsNotEquals(string file, int line, double nbrA, double nbrB){ 161 | if(nbrA==nbrB){ // If strings are differents 162 | string message = "IsNotEquals("+DoubleToString(nbrA)+","+DoubleToString(nbrB)+")"; 163 | this.AddFailedTest(file, line, message); // Add a fail test 164 | return false; 165 | } 166 | else 167 | return true; 168 | } 169 | 170 | //+------------------------------------------------------------------+ 171 | //| Set the Unit Test as false directly for a certain reason 172 | //| @param expected What was expected 173 | //| @param reality What really happen 174 | //+------------------------------------------------------------------+ 175 | 176 | void CUnitTests::SetFalse(string file, int line, string message){ 177 | this.AddFailedTest(file, line, message); // Add a fail test 178 | } 179 | 180 | //+------------------------------------------------------------------+ 181 | //| Get the failed test by its position in the list 182 | //| @return The failed if a test exists at this position, NULL otherwise 183 | //+------------------------------------------------------------------+ 184 | 185 | CFailedUnitTest* CUnitTests::GetFailedTest(int position){ 186 | return m_failedTestsList.GetNodeAtIndex(position); 187 | } 188 | 189 | //+------------------------------------------------------------------+ 190 | //| Get the total of failed tests 191 | //| @return The total of failed tests 192 | //+------------------------------------------------------------------+ 193 | 194 | int CUnitTests::TotalFailedTests(void){ 195 | return m_failedTestsList.Total(); 196 | } 197 | 198 | //+------------------------------------------------------------------+ 199 | //| Get the name of the unit test 200 | //| @return The unit test name 201 | //+------------------------------------------------------------------+ 202 | 203 | string CUnitTests::GetName(){ 204 | return m_name; 205 | } 206 | 207 | //+------------------------------------------------------------------+ 208 | --------------------------------------------------------------------------------