From ab741455185091e3c1f9ac963c6e8e14808b57f5 Mon Sep 17 00:00:00 2001 From: Muhammad Tayayb Tahir Qureshi Date: Tue, 25 Jun 2024 15:16:46 +0500 Subject: [PATCH 1/7] test: Add test for WeatherParser.parse_weather_file() method --- unittests/test_weather_parser.py | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 unittests/test_weather_parser.py diff --git a/unittests/test_weather_parser.py b/unittests/test_weather_parser.py new file mode 100644 index 0000000..976b387 --- /dev/null +++ b/unittests/test_weather_parser.py @@ -0,0 +1,50 @@ +import os +import sys +import unittest +from tempfile import NamedTemporaryFile + +sys.path.append(os.path.join(os.path.dirname(__file__), '..')) +from code_files.weather_parser import WeatherParser +from code_files.weather_readings import WeatherReading + +SAMPLE_DATA = """PKT,Max TemperatureC,Mean TemperatureC,Min TemperatureC,Dew PointC,MeanDew PointC,Min DewpointC,Max Humidity, Mean Humidity, Min Humidity, Max Sea Level PressurehPa, Mean Sea Level PressurehPa, Min Sea Level PressurehPa, Max VisibilityKm, Mean VisibilityKm, Min VisibilitykM, Max Wind SpeedKm/h, Mean Wind SpeedKm/h, Max Gust SpeedKm/h,Precipitationmm, CloudCover, Events,WindDirDegrees +2012-2-1,9,6,3,-4,-5,-7,36,34,31,,,,10.0,7.0,4.0,11,8,,0.0,,,-1 +2012-2-2,12,8,5,0,-4,-7,47,34,24,,,,10.0,7.0,4.0,18,12,,0.0,8,,-1 +2012-2-3,2,1,-2,0,-3,-6,100,71,33,,,,4.0,2.0,0.1,11,4,,13.0,8,Snow,-1 +2012-2-4,0,-0,-2,-4,-4,-5,76,74,71,,,,0.1,0.1,0.1,7,5,,48.0,8,Snow,-1 +2012-2-5,3,0,-3,-0,-3,-6,87,77,70,,,,10.0,6.0,0.1,4,1,,15.0,8,Snow,-1 +""" + +class TestWeatherParser(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.temp_file = NamedTemporaryFile( + delete=False, + mode="w", + newline="", + suffix=".txt", + ) + cls.temp_file_name = cls.temp_file.name + cls.temp_file.write(SAMPLE_DATA) + cls.temp_file_path = os.path.join(os.getcwd(), cls.temp_file_name) + cls.temp_file.close() + cls.weather_parser = WeatherParser() + cls.weather_parser.parse_weather_file(cls.temp_file_name) + + @classmethod + def tearDownClass(cls): + os.remove(cls.temp_file_name) + + def test_parse_weather_file_total_readings(self): + self.assertEqual(len(self.weather_parser.weather_readings), 5) + + def test_parse_weather_file_values(self): + self.assertEqual(self.weather_parser.weather_readings[0], WeatherReading('2012-2-1',9,3,36,34)) + self.assertEqual(self.weather_parser.weather_readings[1], WeatherReading('2012-2-2',12,5,47,34)) + self.assertEqual(self.weather_parser.weather_readings[2], WeatherReading('2012-2-3',2,-2,100,71)) + self.assertEqual(self.weather_parser.weather_readings[3], WeatherReading('2012-2-4',0,-2,76,74)) + self.assertEqual(self.weather_parser.weather_readings[4], WeatherReading('2012-2-5',3,-3,87,77)) + + +if __name__ == "__main__": + unittest.main() From 5c126585e629dc1a564743aaab004f9378a07a19 Mon Sep 17 00:00:00 2001 From: Muhammad Tayayb Tahir Qureshi Date: Wed, 26 Jun 2024 10:51:58 +0500 Subject: [PATCH 2/7] test: Add unit tests for ReportCalculator class This commit adds two new unit tests to the TestReportCalculator class: 1. test_compute_extreme_stats 2. test_compute_average_stats --- unittests/test_report_calculator.py | 62 +++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 unittests/test_report_calculator.py diff --git a/unittests/test_report_calculator.py b/unittests/test_report_calculator.py new file mode 100644 index 0000000..e059974 --- /dev/null +++ b/unittests/test_report_calculator.py @@ -0,0 +1,62 @@ +import os +import sys +import unittest + +sys.path.append(os.path.join(os.path.dirname(__file__), "..")) +from code_files.weather_app import ReportCalculator, WeatherReading, WeatherExtremes + +weather_reading1 = WeatherReading("2012-2-1", 9, 3, 36, 34) +weather_reading2 = WeatherReading("2012-2-2", 12, 5, 47, 34) +weather_reading3 = WeatherReading("2012-2-3", 2, -2, 100, 71) +weather_reading4 = WeatherReading("2012-2-4", 0, -2, 76, 74) +weather_reading5 = WeatherReading("2012-2-5", 3, -3, 87, 77) + + +class TestReportCalculator(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.readings = [ + weather_reading1, + weather_reading2, + weather_reading3, + weather_reading4, + weather_reading5, + ] + cls.report_calculator = ReportCalculator(cls.readings) + + @classmethod + def tearDownClass(cls): + del cls.readings + del cls.report_calculator + + def test_compute_extreme_stats(self): + """Test the compute_extreme_stats method of the ReportCalculator class. + + The purpose of this test is to ensure that the compute_extreme_stats method correctly + calculates the weather extremes based on the input data. + """ + self.weather_extremes = WeatherExtremes( + 12, -3, 100, ["2012", "2", "2"], ["2012", "2", "5"], ["2012", "2", "3"] + ) + self.assertEqual( + self.weather_extremes, self.report_calculator.compute_extreme_stats() + ) + + def test_compute_average_stats(self): + """Test the compute_average_stats method of the ReportCalculator class. + + This test sets up expected values for the avg_max_temp, avg_min_temp and + avg_mean_humidity. It then calls the compute_average_stats method of the + ReportCalculator class and asserts that the returned values match the + expected values. + """ + self.avg_max_temp = 5.2 + self.avg_min_temp = 0.2 + self.avg_mean_humidity = 58 + self.result = (self.avg_max_temp, self.avg_min_temp, self.avg_mean_humidity) + + self.assertEqual(self.report_calculator.compute_average_stats(), self.result) + + +if __name__ == "__main__": + unittest.main(verbosity=2) From db534a781912fa42dc9c565925d41bfdd97b5019 Mon Sep 17 00:00:00 2001 From: Muhammad Tayayb Tahir Qureshi Date: Wed, 26 Jun 2024 11:07:52 +0500 Subject: [PATCH 3/7] Organizing imports --- code_files/weather_app.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/code_files/weather_app.py b/code_files/weather_app.py index 3973b04..15ed57c 100644 --- a/code_files/weather_app.py +++ b/code_files/weather_app.py @@ -1,5 +1,12 @@ from code_files.weather_parser import WeatherParser from code_files.weather_reporter import WeatherReporter from code_files.report_calculator import ReportCalculator +from code_files.weather_readings import WeatherReading, WeatherExtremes -__all__ = ['WeatherParser', 'WeatherReporter', 'ReportCalculator'] \ No newline at end of file +__all__ = [ + "WeatherParser", + "WeatherReporter", + "ReportCalculator", + "WeatherReading", + "WeatherExtremes", +] From 01ed0aebffd82e1e8634bf279ee38c385ac00b44 Mon Sep 17 00:00:00 2001 From: Muhammad Tayayb Tahir Qureshi Date: Wed, 26 Jun 2024 11:18:59 +0500 Subject: [PATCH 4/7] doc: Add docstrings for the tests --- unittests/test_weather_parser.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/unittests/test_weather_parser.py b/unittests/test_weather_parser.py index 976b387..60ab5ee 100644 --- a/unittests/test_weather_parser.py +++ b/unittests/test_weather_parser.py @@ -18,6 +18,7 @@ class TestWeatherParser(unittest.TestCase): @classmethod def setUpClass(cls): + """Creates a temporary file and populates the SAMPLE_DATA in it for subsequent tests to use.""" cls.temp_file = NamedTemporaryFile( delete=False, mode="w", @@ -36,9 +37,13 @@ def tearDownClass(cls): os.remove(cls.temp_file_name) def test_parse_weather_file_total_readings(self): + """Tests that the parse_weather_file method reads all readings from the input data.""" + self.assertEqual(len(self.weather_parser.weather_readings), 5) def test_parse_weather_file_values(self): + """Tests that the parse_weather_file method correctly parses the weather data values.""" + self.assertEqual(self.weather_parser.weather_readings[0], WeatherReading('2012-2-1',9,3,36,34)) self.assertEqual(self.weather_parser.weather_readings[1], WeatherReading('2012-2-2',12,5,47,34)) self.assertEqual(self.weather_parser.weather_readings[2], WeatherReading('2012-2-3',2,-2,100,71)) From b2fe8da415c897cb01052c44625586edfe7c5a14 Mon Sep 17 00:00:00 2001 From: Muhammad Tayayb Tahir Qureshi Date: Wed, 26 Jun 2024 11:21:43 +0500 Subject: [PATCH 5/7] UPDATE .gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ee730d8..a3c092a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,7 @@ rough/ weatherfiles/ weatherfiles.zip FileTree.ini -.vscode/ \ No newline at end of file +.vscode/ +unittests/test_weather_reporter.py +unittests/test_weatherman.py + From aced1f03e0bda030ce8af3be8b6a910d624ab58a Mon Sep 17 00:00:00 2001 From: Muhammad Tayayb Tahir Qureshi Date: Wed, 26 Jun 2024 11:45:28 +0500 Subject: [PATCH 6/7] test: Add test for validate_reading method of WeatherReading class --- unittests/test_weather_readings.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 unittests/test_weather_readings.py diff --git a/unittests/test_weather_readings.py b/unittests/test_weather_readings.py new file mode 100644 index 0000000..2136113 --- /dev/null +++ b/unittests/test_weather_readings.py @@ -0,0 +1,27 @@ +import os +import sys +import unittest + +sys.path.append(os.path.join(os.path.dirname(__file__), "..")) +from code_files.weather_app import WeatherReading + + +class TestWeatherReading(unittest.TestCase): + def test_validate_reading(self): + """Tests the functionality of validate_reading method of WeatherReading class.""" + + self.assertEqual(WeatherReading.validate_reading(10), 10) + self.assertEqual(WeatherReading.validate_reading("10"), 10) + + self.assertEqual(WeatherReading.validate_reading(-4), -4) + self.assertEqual(WeatherReading.validate_reading("-4"), -4) + + self.assertEqual(WeatherReading.validate_reading(0), 0) + self.assertEqual(WeatherReading.validate_reading("0"), 0) + + self.assertIsNone(WeatherReading.validate_reading("")) + self.assertIsNone(WeatherReading.validate_reading(None)) + + +if __name__ == "__main__": + unittest.main() From 87e0bc16d574ef46a53e710cf27aaca20ba587f5 Mon Sep 17 00:00:00 2001 From: Muhammad Tayayb Tahir Qureshi Date: Wed, 26 Jun 2024 12:39:10 +0500 Subject: [PATCH 7/7] test: add test_suite --- unittests/test_suite.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 unittests/test_suite.py diff --git a/unittests/test_suite.py b/unittests/test_suite.py new file mode 100644 index 0000000..ea04105 --- /dev/null +++ b/unittests/test_suite.py @@ -0,0 +1,21 @@ +import unittest + +from test_report_calculator import TestReportCalculator +from test_weather_parser import TestWeatherParser +from test_weather_readings import TestWeatherReading + + +def test_suite(): + """This function creates a test suite containing all the test cases + for the ReportCalculator, WeatherParser, and WeatherReadings. + """ + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(TestReportCalculator)) + suite.addTest(unittest.makeSuite(TestWeatherParser)) + suite.addTest(unittest.makeSuite(TestWeatherReading)) + + runner = unittest.TextTestRunner(verbosity=2) + print(runner.run(suite)) + + +test_suite()