How to use some_test method in Nose

Best Python code snippet using nose

expectations_unittest.py

Source:expectations_unittest.py Github

copy

Full Screen

1#!/usr/bin/env vpython32# Copyright 2021 The Chromium Authors. All rights reserved.3# Use of this source code is governed by a BSD-style license that can be4# found in the LICENSE file.5import base646import os7import sys8import tempfile9import unittest10import six11# Same reasoning as below.12if six.PY3:13 import urllib.error14# This script is not Python 2-compatible, but some presubmit scripts end up15# trying to parse this to find tests.16# TODO(crbug.com/1198237): Remove this once all the GPU tests, and by17# extension the presubmit scripts, are Python 3-compatible.18if six.PY3:19 import unittest.mock as mock20import validate_tag_consistency21from pyfakefs import fake_filesystem_unittest22from flake_suppressor import expectations23from flake_suppressor import unittest_utils as uu24# Note for all tests in this class: We can safely check the contents of the file25# at the end despite potentially having multiple added lines because Python 3.7+26# guarantees that dictionaries remember insertion order, so there is no risk of27# the order of modification changing.28@unittest.skipIf(sys.version_info[0] != 3, 'Python 3-only')29class IterateThroughResultsForUserUnittest(fake_filesystem_unittest.TestCase):30 def setUp(self):31 self._new_stdout = open(os.devnull, 'w')32 self.setUpPyfakefs()33 # Redirect stdout since the tested function prints a lot.34 self._old_stdout = sys.stdout35 sys.stdout = self._new_stdout36 self._input_patcher = mock.patch.object(expectations,37 'PromptUserForExpectationAction')38 self._input_mock = self._input_patcher.start()39 self.addCleanup(self._input_patcher.stop)40 self.result_map = {41 'pixel_integration_test': {42 'foo_test': {43 tuple(['win']): ['a'],44 tuple(['mac']): ['b'],45 },46 'bar_test': {47 tuple(['win']): ['c'],48 },49 },50 }51 self.expectation_file = os.path.join(52 expectations.ABSOLUTE_EXPECTATION_FILE_DIRECTORY,53 'pixel_expectations.txt')54 uu.CreateFile(self, self.expectation_file)55 expectation_file_contents = validate_tag_consistency.TAG_HEADER + """\56[ win ] some_test [ Failure ]57[ mac ] some_test [ Failure ]58[ android ] some_test [ Failure ]59"""60 with open(self.expectation_file, 'w') as outfile:61 outfile.write(expectation_file_contents)62 def tearDown(self):63 sys.stdout = self._old_stdout64 self._new_stdout.close()65 def testIterateThroughResultsForUserIgnoreNoGroupByTags(self):66 """Tests that everything appears to function with ignore and no group."""67 self._input_mock.return_value = (None, None)68 expectations.IterateThroughResultsForUser(self.result_map, False, True)69 expected_contents = validate_tag_consistency.TAG_HEADER + """\70[ win ] some_test [ Failure ]71[ mac ] some_test [ Failure ]72[ android ] some_test [ Failure ]73"""74 with open(self.expectation_file) as infile:75 self.assertEqual(infile.read(), expected_contents)76 def testIterateThroughResultsForUserIgnoreGroupByTags(self):77 """Tests that everything appears to function with ignore and grouping."""78 self._input_mock.return_value = (None, None)79 expectations.IterateThroughResultsForUser(self.result_map, True, True)80 expected_contents = validate_tag_consistency.TAG_HEADER + """\81[ win ] some_test [ Failure ]82[ mac ] some_test [ Failure ]83[ android ] some_test [ Failure ]84"""85 with open(self.expectation_file) as infile:86 self.assertEqual(infile.read(), expected_contents)87 def testIterateThroughResultsForUserRetryNoGroupByTags(self):88 """Tests that everything appears to function with retry and no group."""89 self._input_mock.return_value = ('RetryOnFailure', '')90 expectations.IterateThroughResultsForUser(self.result_map, False, True)91 expected_contents = validate_tag_consistency.TAG_HEADER + """\92[ win ] some_test [ Failure ]93[ mac ] some_test [ Failure ]94[ android ] some_test [ Failure ]95[ win ] foo_test [ RetryOnFailure ]96[ mac ] foo_test [ RetryOnFailure ]97[ win ] bar_test [ RetryOnFailure ]98"""99 with open(self.expectation_file) as infile:100 self.assertEqual(infile.read(), expected_contents)101 def testIterateThroughResultsForUserRetryGroupByTags(self):102 """Tests that everything appears to function with retry and grouping."""103 self._input_mock.return_value = ('RetryOnFailure', 'crbug.com/1')104 expectations.IterateThroughResultsForUser(self.result_map, True, True)105 expected_contents = validate_tag_consistency.TAG_HEADER + """\106[ win ] some_test [ Failure ]107crbug.com/1 [ win ] foo_test [ RetryOnFailure ]108crbug.com/1 [ win ] bar_test [ RetryOnFailure ]109[ mac ] some_test [ Failure ]110crbug.com/1 [ mac ] foo_test [ RetryOnFailure ]111[ android ] some_test [ Failure ]112"""113 with open(self.expectation_file) as infile:114 self.assertEqual(infile.read(), expected_contents)115 def testIterateThroughResultsForUserFailNoGroupByTags(self):116 """Tests that everything appears to function with failure and no group."""117 self._input_mock.return_value = ('Failure', 'crbug.com/1')118 expectations.IterateThroughResultsForUser(self.result_map, False, True)119 expected_contents = validate_tag_consistency.TAG_HEADER + """\120[ win ] some_test [ Failure ]121[ mac ] some_test [ Failure ]122[ android ] some_test [ Failure ]123crbug.com/1 [ win ] foo_test [ Failure ]124crbug.com/1 [ mac ] foo_test [ Failure ]125crbug.com/1 [ win ] bar_test [ Failure ]126"""127 with open(self.expectation_file) as infile:128 self.assertEqual(infile.read(), expected_contents)129 def testIterateThroughResultsForUserFailGroupByTags(self):130 """Tests that everything appears to function with failure and grouping."""131 self._input_mock.return_value = ('Failure', '')132 expectations.IterateThroughResultsForUser(self.result_map, True, True)133 expected_contents = validate_tag_consistency.TAG_HEADER + """\134[ win ] some_test [ Failure ]135[ win ] foo_test [ Failure ]136[ win ] bar_test [ Failure ]137[ mac ] some_test [ Failure ]138[ mac ] foo_test [ Failure ]139[ android ] some_test [ Failure ]140"""141 with open(self.expectation_file) as infile:142 self.assertEqual(infile.read(), expected_contents)143 def testIterateThroughResultsForUserNoIncludeAllTags(self):144 """Tests that everything appears to function without including all tags"""145 self.result_map = {146 'pixel_integration_test': {147 'foo_test': {148 tuple(['win', 'win10']): ['a'],149 tuple(['mac']): ['b'],150 },151 'bar_test': {152 tuple(['win']): ['c'],153 },154 },155 }156 self._input_mock.return_value = ('RetryOnFailure', '')157 expectations.IterateThroughResultsForUser(self.result_map, False, False)158 expected_contents = validate_tag_consistency.TAG_HEADER + """\159[ win ] some_test [ Failure ]160[ mac ] some_test [ Failure ]161[ android ] some_test [ Failure ]162[ win10 ] foo_test [ RetryOnFailure ]163[ mac ] foo_test [ RetryOnFailure ]164[ win ] bar_test [ RetryOnFailure ]165"""166 with open(self.expectation_file) as infile:167 self.assertEqual(infile.read(), expected_contents)168@unittest.skipIf(sys.version_info[0] != 3, 'Python 3-only')169class IterateThroughResultsWithThresholdsUnittest(170 fake_filesystem_unittest.TestCase):171 def setUp(self):172 self.setUpPyfakefs()173 self.result_map = {174 'pixel_integration_test': {175 'foo_test': {176 tuple(['win']): ['a'],177 tuple(['mac']): ['b'],178 },179 'bar_test': {180 tuple(['win']): ['c'],181 },182 },183 }184 self.expectation_file = os.path.join(185 expectations.ABSOLUTE_EXPECTATION_FILE_DIRECTORY,186 'pixel_expectations.txt')187 uu.CreateFile(self, self.expectation_file)188 expectation_file_contents = validate_tag_consistency.TAG_HEADER + """\189[ win ] some_test [ Failure ]190[ mac ] some_test [ Failure ]191[ android ] some_test [ Failure ]192"""193 with open(self.expectation_file, 'w') as outfile:194 outfile.write(expectation_file_contents)195 def testGroupByTags(self):196 """Tests that threshold-based expectations work when grouping by tags."""197 result_counts = {198 tuple(['win']): {199 # We expect this to be ignored since it has a 1% flake rate.200 'foo_test': 100,201 # We expect this to be RetryOnFailure since it has a 25% flake rate.202 'bar_test': 4,203 },204 tuple(['mac']): {205 # We expect this to be Failure since it has a 50% flake rate.206 'foo_test': 2207 }208 }209 expectations.IterateThroughResultsWithThresholds(self.result_map, True,210 result_counts, 0.02, 0.5,211 True)212 expected_contents = validate_tag_consistency.TAG_HEADER + """\213[ win ] some_test [ Failure ]214[ win ] bar_test [ RetryOnFailure ]215[ mac ] some_test [ Failure ]216[ mac ] foo_test [ Failure ]217[ android ] some_test [ Failure ]218"""219 with open(self.expectation_file) as infile:220 self.assertEqual(infile.read(), expected_contents)221 def testNoGroupByTags(self):222 """Tests that threshold-based expectations work when not grouping by tags"""223 result_counts = {224 tuple(['win']): {225 # We expect this to be ignored since it has a 1% flake rate.226 'foo_test': 100,227 # We expect this to be RetryOnFailure since it has a 25% flake rate.228 'bar_test': 4,229 },230 tuple(['mac']): {231 # We expect this to be Failure since it has a 50% flake rate.232 'foo_test': 2233 }234 }235 expectations.IterateThroughResultsWithThresholds(self.result_map, False,236 result_counts, 0.02, 0.5,237 True)238 expected_contents = validate_tag_consistency.TAG_HEADER + """\239[ win ] some_test [ Failure ]240[ mac ] some_test [ Failure ]241[ android ] some_test [ Failure ]242[ mac ] foo_test [ Failure ]243[ win ] bar_test [ RetryOnFailure ]244"""245 with open(self.expectation_file) as infile:246 self.assertEqual(infile.read(), expected_contents)247 def testNoIncludeAllTags(self):248 """Tests that threshold-based expectations work when filtering tags."""249 self.result_map = {250 'pixel_integration_test': {251 'foo_test': {252 tuple(['win', 'win10']): ['a'],253 tuple(['mac']): ['b'],254 },255 'bar_test': {256 tuple(['win', 'win10']): ['c'],257 },258 },259 }260 result_counts = {261 tuple(['win', 'win10']): {262 # We expect this to be ignored since it has a 1% flake rate.263 'foo_test': 100,264 # We expect this to be RetryOnFailure since it has a 25% flake rate.265 'bar_test': 4,266 },267 tuple(['mac']): {268 # We expect this to be Failure since it has a 50% flake rate.269 'foo_test': 2270 }271 }272 expectations.IterateThroughResultsWithThresholds(self.result_map, False,273 result_counts, 0.02, 0.5,274 False)275 expected_contents = validate_tag_consistency.TAG_HEADER + """\276[ win ] some_test [ Failure ]277[ mac ] some_test [ Failure ]278[ android ] some_test [ Failure ]279[ mac ] foo_test [ Failure ]280[ win10 ] bar_test [ RetryOnFailure ]281"""282 with open(self.expectation_file) as infile:283 self.assertEqual(infile.read(), expected_contents)284@unittest.skipIf(sys.version_info[0] != 3, 'Python 3-only')285class FindFailuresInSameConditionUnittest(unittest.TestCase):286 def setUp(self):287 self.result_map = {288 'pixel_integration_test': {289 'foo_test': {290 tuple(['win']): ['a'],291 tuple(['mac']): ['a', 'b'],292 },293 'bar_test': {294 tuple(['win']): ['a', 'b', 'c'],295 tuple(['mac']): ['a', 'b', 'c', 'd'],296 },297 },298 'webgl_conformance_integration_test': {299 'foo_test': {300 tuple(['win']): ['a', 'b', 'c', 'd', 'e'],301 tuple(['mac']): ['a', 'b', 'c', 'd', 'e', 'f'],302 },303 'bar_test': {304 tuple(['win']): ['a', 'b', 'c', 'd', 'e', 'f', 'g'],305 tuple(['mac']): ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],306 },307 },308 }309 def testFindFailuresInSameTest(self):310 other_failures = expectations.FindFailuresInSameTest(311 self.result_map, 'pixel_integration_test', 'foo_test', ['win'])312 self.assertEqual(other_failures, [(tuple(['mac']), 2)])313 def testFindFailuresInSameConfig(self):314 typ_tag_ordered_result_map = expectations._ReorderMapByTypTags(315 self.result_map)316 other_failures = expectations.FindFailuresInSameConfig(317 typ_tag_ordered_result_map, 'pixel_integration_test', 'foo_test',318 ['win'])319 expected_other_failures = [320 ('pixel_integration_test.bar_test', 3),321 ('webgl_conformance_integration_test.foo_test', 5),322 ('webgl_conformance_integration_test.bar_test', 7),323 ]324 self.assertEqual(len(other_failures), len(expected_other_failures))325 self.assertEqual(set(other_failures), set(expected_other_failures))326@unittest.skipIf(sys.version_info[0] != 3, 'Python 3-only')327class ModifyFileForResultUnittest(fake_filesystem_unittest.TestCase):328 def setUp(self):329 self.setUpPyfakefs()330 self.expectation_file = os.path.join(331 expectations.ABSOLUTE_EXPECTATION_FILE_DIRECTORY, 'expectation.txt')332 uu.CreateFile(self, self.expectation_file)333 self._expectation_file_patcher = mock.patch.object(334 expectations, 'GetExpectationFileForSuite')335 self._expectation_file_mock = self._expectation_file_patcher.start()336 self.addCleanup(self._expectation_file_patcher.stop)337 self._expectation_file_mock.return_value = self.expectation_file338 def testNoGroupByTags(self):339 """Tests that not grouping by tags appends to the end."""340 expectation_file_contents = validate_tag_consistency.TAG_HEADER + """\341[ win ] some_test [ Failure ]342[ mac ] some_test [ Failure ]343"""344 with open(self.expectation_file, 'w') as outfile:345 outfile.write(expectation_file_contents)346 expectations.ModifyFileForResult(None, 'some_test', ['win', 'win10'], '',347 'Failure', False, True)348 expected_contents = validate_tag_consistency.TAG_HEADER + """\349[ win ] some_test [ Failure ]350[ mac ] some_test [ Failure ]351[ win win10 ] some_test [ Failure ]352"""353 with open(self.expectation_file) as infile:354 self.assertEqual(infile.read(), expected_contents)355 def testGroupByTagsNoMatch(self):356 """Tests that grouping by tags but finding no match appends to the end."""357 expectation_file_contents = validate_tag_consistency.TAG_HEADER + """\358[ mac ] some_test [ Failure ]359"""360 with open(self.expectation_file, 'w') as outfile:361 outfile.write(expectation_file_contents)362 expectations.ModifyFileForResult(None, 'some_test', ['win', 'win10'], '',363 'Failure', True, True)364 expected_contents = validate_tag_consistency.TAG_HEADER + """\365[ mac ] some_test [ Failure ]366[ win win10 ] some_test [ Failure ]367"""368 with open(self.expectation_file) as infile:369 self.assertEqual(infile.read(), expected_contents)370 def testGroupByTagsMatch(self):371 """Tests that grouping by tags and finding a match adds mid-file."""372 expectation_file_contents = validate_tag_consistency.TAG_HEADER + """\373[ win ] some_test [ Failure ]374[ mac ] some_test [ Failure ]375"""376 with open(self.expectation_file, 'w') as outfile:377 outfile.write(expectation_file_contents)378 expectations.ModifyFileForResult(None, 'foo_test', ['win', 'win10'], '',379 'Failure', True, True)380 expected_contents = validate_tag_consistency.TAG_HEADER + """\381[ win ] some_test [ Failure ]382[ win ] foo_test [ Failure ]383[ mac ] some_test [ Failure ]384"""385 with open(self.expectation_file) as infile:386 self.assertEqual(infile.read(), expected_contents)387@unittest.skipIf(sys.version_info[0] != 3, 'Python 3-only')388class FilterToMostSpecificTagTypeUnittest(fake_filesystem_unittest.TestCase):389 def setUp(self):390 self.setUpPyfakefs()391 with tempfile.NamedTemporaryFile(delete=False) as tf:392 self.expectation_file = tf.name393 def testBasic(self):394 """Tests that only the most specific tags are kept."""395 expectation_file_contents = """\396# tags: [ tag1_least_specific tag1_middle_specific tag1_most_specific ]397# tags: [ tag2_least_specific tag2_middle_specific tag2_most_specific ]"""398 with open(self.expectation_file, 'w') as outfile:399 outfile.write(expectation_file_contents)400 tags = [401 'tag1_least_specific', 'tag1_most_specific', 'tag2_middle_specific',402 'tag2_least_specific'403 ]404 filtered_tags = expectations.FilterToMostSpecificTypTags(405 tags, self.expectation_file)406 self.assertEqual(filtered_tags,407 ['tag1_most_specific', 'tag2_middle_specific'])408 def testSingleTags(self):409 """Tests that functionality works as expected with single tags."""410 expectation_file_contents = """\411# tags: [ tag1_most_specific ]412# tags: [ tag2_most_specific ]"""413 with open(self.expectation_file, 'w') as outfile:414 outfile.write(expectation_file_contents)415 tags = ['tag1_most_specific', 'tag2_most_specific']416 filtered_tags = expectations.FilterToMostSpecificTypTags(417 tags, self.expectation_file)418 self.assertEqual(filtered_tags, tags)419 def testUnusedTags(self):420 """Tests that functionality works as expected with extra/unused tags."""421 expectation_file_contents = """\422# tags: [ tag1_least_specific tag1_middle_specific tag1_most_specific ]423# tags: [ tag2_least_specific tag2_middle_specific tag2_most_specific ]424# tags: [ some_unused_tag ]"""425 with open(self.expectation_file, 'w') as outfile:426 outfile.write(expectation_file_contents)427 tags = [428 'tag1_least_specific', 'tag1_most_specific', 'tag2_middle_specific',429 'tag2_least_specific'430 ]431 filtered_tags = expectations.FilterToMostSpecificTypTags(432 tags, self.expectation_file)433 self.assertEqual(filtered_tags,434 ['tag1_most_specific', 'tag2_middle_specific'])435 def testMultiline(self):436 """Tests that functionality works when tags cover multiple lines."""437 expectation_file_contents = """\438# tags: [ tag1_least_specific439# tag1_middle_specific440# tag1_most_specific ]441# tags: [ tag2_least_specific442# tag2_middle_specific tag2_most_specific ]"""443 with open(self.expectation_file, 'w') as outfile:444 outfile.write(expectation_file_contents)445 tags = [446 'tag1_least_specific', 'tag1_middle_specific', 'tag1_most_specific',447 'tag2_middle_specific', 'tag2_least_specific'448 ]449 filtered_tags = expectations.FilterToMostSpecificTypTags(450 tags, self.expectation_file)451 self.assertEqual(filtered_tags,452 ['tag1_most_specific', 'tag2_middle_specific'])453 def testMissingTags(self):454 """Tests that a file not having all tags is an error."""455 expectation_file_contents = """\456# tags: [ tag1_least_specific tag1_middle_specific ]457# tags: [ tag2_least_specific tag2_middle_specific tag2_most_specific ]"""458 with open(self.expectation_file, 'w') as outfile:459 outfile.write(expectation_file_contents)460 tags = [461 'tag1_least_specific', 'tag1_most_specific', 'tag2_middle_specific',462 'tag2_least_specific'463 ]464 with self.assertRaises(RuntimeError):465 expectations.FilterToMostSpecificTypTags(tags, self.expectation_file)466@unittest.skipIf(sys.version_info[0] != 3, 'Python 3-only')467class GetExpectationFileForSuiteUnittest(unittest.TestCase):468 def testRegularExpectationFile(self):469 """Tests that a regular expectation file is found properly."""470 expected_filepath = os.path.join(471 expectations.ABSOLUTE_EXPECTATION_FILE_DIRECTORY,472 'pixel_expectations.txt')473 actual_filepath = expectations.GetExpectationFileForSuite(474 'pixel_integration_test', ['webgl-version-2'])475 self.assertEqual(actual_filepath, expected_filepath)476 def testOverrideExpectationFile(self):477 """Tests that an overridden expectation file is found properly."""478 expected_filepath = os.path.join(479 expectations.ABSOLUTE_EXPECTATION_FILE_DIRECTORY,480 'info_collection_expectations.txt')481 actual_filepath = expectations.GetExpectationFileForSuite(482 'info_collection_test', ['webgl-version-2'])483 self.assertEqual(actual_filepath, expected_filepath)484 def testWebGl1Conformance(self):485 """Tests that a WebGL 1 expectation file is found properly."""486 expected_filepath = os.path.join(487 expectations.ABSOLUTE_EXPECTATION_FILE_DIRECTORY,488 'webgl_conformance_expectations.txt')489 actual_filepath = expectations.GetExpectationFileForSuite(490 'webgl_conformance_integration_test', [])491 self.assertEqual(actual_filepath, expected_filepath)492 def testWebGl2Conformance(self):493 """Tests that a WebGL 2 expectation file is found properly."""494 expected_filepath = os.path.join(495 expectations.ABSOLUTE_EXPECTATION_FILE_DIRECTORY,496 'webgl2_conformance_expectations.txt')497 actual_filepath = expectations.GetExpectationFileForSuite(498 'webgl_conformance_integration_test', ['webgl-version-2'])499 self.assertEqual(actual_filepath, expected_filepath)500@unittest.skipIf(sys.version_info[0] != 3, 'Python 3-only')501class FindBestInsertionLineForExpectationUnittest(502 fake_filesystem_unittest.TestCase):503 def setUp(self):504 self.setUpPyfakefs()505 self.expectation_file = os.path.join(506 expectations.ABSOLUTE_EXPECTATION_FILE_DIRECTORY, 'expectation.txt')507 uu.CreateFile(self, self.expectation_file)508 expectation_file_contents = validate_tag_consistency.TAG_HEADER + """\509[ win ] some_test [ Failure ]510[ mac ] some_test [ Failure ]511[ win release ] bar_test [ Failure ]512[ win ] foo_test [ Failure ]513[ chromeos ] some_test [ Failure ]514"""515 with open(self.expectation_file, 'w') as outfile:516 outfile.write(expectation_file_contents)517 def testNoMatchingTags(self):518 """Tests behavior when there are no expectations with matching tags."""519 insertion_line, tags = expectations.FindBestInsertionLineForExpectation(520 ['android'], self.expectation_file)521 self.assertEqual(insertion_line, -1)522 self.assertEqual(tags, set())523 def testMatchingTagsLastEntryChosen(self):524 """Tests that the last matching line is chosen."""525 insertion_line, tags = expectations.FindBestInsertionLineForExpectation(526 ['win'], self.expectation_file)527 # We expect "[ win ] foo_test [ Failure ]" to be chosen528 expected_line = len(validate_tag_consistency.TAG_HEADER.splitlines()) + 6529 self.assertEqual(insertion_line, expected_line)530 self.assertEqual(tags, set(['win']))531 def testMatchingTagsClosestMatchChosen(self):532 """Tests that the closest tag match is chosen."""533 insertion_line, tags = expectations.FindBestInsertionLineForExpectation(534 ['win', 'release'], self.expectation_file)535 # We expect "[ win release ] bar_test [ Failure ]" to be chosen536 expected_line = len(validate_tag_consistency.TAG_HEADER.splitlines()) + 5537 self.assertEqual(insertion_line, expected_line)538 self.assertEqual(tags, set(['win', 'release']))539class GetExpectationFilesFromOriginUnittest(unittest.TestCase):540 class FakeRequestResult(object):541 def __init__(self):542 self.text = ''543 def read(self):544 return self.text545 def setUp(self):546 self._get_patcher = mock.patch(547 'flake_suppressor.expectations.urllib.request.urlopen')548 self._get_mock = self._get_patcher.start()549 self.addCleanup(self._get_patcher.stop)550 def testBasic(self):551 """Tests basic functionality along the happy path."""552 def SideEffect(url):553 request_result = GetExpectationFilesFromOriginUnittest.FakeRequestResult()554 text = ''555 if url.endswith('test_expectations?format=TEXT'):556 text = """\557mode type hash foo_tests.txt558mode type hash bar_tests.txt"""559 elif url.endswith('foo_tests.txt?format=TEXT'):560 text = 'foo_tests.txt content'561 elif url.endswith('bar_tests.txt?format=TEXT'):562 text = 'bar_tests.txt content'563 else:564 self.fail('Given unhandled URL %s' % url)565 request_result.text = base64.b64encode(text.encode('utf-8'))566 return request_result567 self._get_mock.side_effect = SideEffect568 expected_contents = {569 'foo_tests.txt': 'foo_tests.txt content',570 'bar_tests.txt': 'bar_tests.txt content',571 }572 self.assertEqual(expectations.GetExpectationFilesFromOrigin(),573 expected_contents)574 self.assertEqual(self._get_mock.call_count, 3)575 def testNonOkStatusCodesSurfaced(self):576 """Tests that getting a non-200 status code back results in a failure."""577 def SideEffect(_):578 raise urllib.error.HTTPError('url', '404', 'No exist :(', '', None)579 self._get_mock.side_effect = SideEffect580 with self.assertRaises(urllib.error.HTTPError):581 expectations.GetExpectationFilesFromOrigin()582class GetExpectationFilesFromLocalCheckoutUnittest(583 fake_filesystem_unittest.TestCase):584 def setUp(self):585 self.setUpPyfakefs()586 def testBasic(self):587 """Tests basic functionality."""588 os.makedirs(expectations.ABSOLUTE_EXPECTATION_FILE_DIRECTORY)589 with open(590 os.path.join(expectations.ABSOLUTE_EXPECTATION_FILE_DIRECTORY,591 'foo.txt'), 'w') as outfile:592 outfile.write('foo.txt contents')593 with open(594 os.path.join(expectations.ABSOLUTE_EXPECTATION_FILE_DIRECTORY,595 'bar.txt'), 'w') as outfile:596 outfile.write('bar.txt contents')597 expected_contents = {598 'foo.txt': 'foo.txt contents',599 'bar.txt': 'bar.txt contents',600 }601 self.assertEqual(expectations.GetExpectationFilesFromLocalCheckout(),602 expected_contents)603class AssertCheckoutIsUpToDateUnittest(unittest.TestCase):604 def setUp(self):605 self._origin_patcher = mock.patch(606 'flake_suppressor.expectations.GetExpectationFilesFromOrigin')607 self._origin_mock = self._origin_patcher.start()608 self.addCleanup(self._origin_patcher.stop)609 self._local_patcher = mock.patch(610 'flake_suppressor.expectations.GetExpectationFilesFromLocalCheckout')611 self._local_mock = self._local_patcher.start()612 self.addCleanup(self._local_patcher.stop)613 def testContentsMatch(self):614 """Tests the happy path where the contents match."""615 self._origin_mock.return_value = {616 'foo.txt': 'foo_content',617 'bar.txt': 'bar_content',618 }619 self._local_mock.return_value = {620 'bar.txt': 'bar_content',621 'foo.txt': 'foo_content',622 }623 expectations.AssertCheckoutIsUpToDate()624 def testContentsDoNotMatch(self):625 """Tests that mismatched contents results in a failure."""626 self._origin_mock.return_value = {627 'foo.txt': 'foo_content',628 'bar.txt': 'bar_content',629 }630 # Differing keys.631 self._local_mock.return_value = {632 'bar.txt': 'bar_content',633 'foo2.txt': 'foo_content',634 }635 with self.assertRaises(RuntimeError):636 expectations.AssertCheckoutIsUpToDate()637 # Differing values.638 self._local_mock.return_value = {639 'bar.txt': 'bar_content',640 'foo.txt': 'foo_content2',641 }642 with self.assertRaises(RuntimeError):643 expectations.AssertCheckoutIsUpToDate()644if __name__ == '__main__':...

Full Screen

Full Screen

json_generators_unittest.py

Source:json_generators_unittest.py Github

copy

Full Screen

1#!/usr/bin/env python2# Copyright (C) 2012 Google Inc. All rights reserved.3#4# Redistribution and use in source and binary forms, with or without5# modification, are permitted provided that the following conditions are6# met:7#8# * Redistributions of source code must retain the above copyright9# notice, this list of conditions and the following disclaimer.10# * Redistributions in binary form must reproduce the above11# copyright notice, this list of conditions and the following disclaimer12# in the documentation and/or other materials provided with the13# distribution.14# * Neither the name of Google Inc. nor the names of its15# contributors may be used to endorse or promote products derived from16# this software without specific prior written permission.17#18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR21# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT22# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,23# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT24# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,25# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY26# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE28# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29import json30import models31import unittest32from google.appengine.ext import testbed33from datetime import datetime34from datetime import timedelta35from json_generators import JSONGeneratorBase36from json_generators import DashboardJSONGenerator37from json_generators import ManifestJSONGenerator38from models_unittest import DataStoreTestsBase39from models import Branch40from models import Build41from models import Builder42from models import Platform43from models import Test44from models import TestResult45def _create_results(branch, platform, builder, test_name, values):46 results = []47 for i, value in enumerate(values):48 build = Build(branch=branch, platform=platform, builder=builder,49 buildNumber=i, revision=100 + i, timestamp=datetime.now())50 build.put()51 result = TestResult(name=test_name, build=build, value=value)52 result.put()53 Test.update_or_insert(test_name, branch, platform)54 results.append(result)55 return results56class JSONGeneratorBaseTest(unittest.TestCase):57 def test_to_json(self):58 class AJSONGenerator(JSONGeneratorBase):59 def value(self):60 return {'key': 'value'}61 self.assertEqual(AJSONGenerator().value(), {"key": "value"})62 self.assertEqual(AJSONGenerator().to_json(), '{"key": "value"}')63class DashboardJSONGeneratorTest(DataStoreTestsBase):64 def test_value_no_branch(self):65 self.assertThereIsNoInstanceOf(Branch)66 self.assertEqual(DashboardJSONGenerator().value(), None)67 def test_value_no_plaforms(self):68 webkit_trunk = Branch.create_if_possible('webkit-trunk', 'WebKit trunk')69 self.assertEqual(DashboardJSONGenerator().value(), {70 'defaultBranch': 'WebKit trunk',71 'branchToId': {'WebKit trunk': webkit_trunk.id},72 'platformToId': {},73 'testToId': {},74 })75 def test_value_single_platform(self):76 webkit_trunk = Branch.create_if_possible('webkit-trunk', 'WebKit trunk')77 some_platform = Platform.create_if_possible('some-platform', 'Some Platform')78 self.assertEqual(DashboardJSONGenerator().value(), {79 'defaultBranch': 'WebKit trunk',80 'branchToId': {'WebKit trunk': webkit_trunk.id},81 'platformToId': {'Some Platform': some_platform.id},82 'testToId': {},83 })84 Test.update_or_insert('some-test', webkit_trunk, some_platform)85 self.assertEqual(DashboardJSONGenerator().value(), {86 'defaultBranch': 'WebKit trunk',87 'branchToId': {'WebKit trunk': webkit_trunk.id},88 'platformToId': {'Some Platform': some_platform.id},89 'testToId': {'some-test': Test.get_by_key_name('some-test').id},90 })91 def test_value_two_platforms(self):92 webkit_trunk = Branch.create_if_possible('webkit-trunk', 'WebKit trunk')93 some_platform = Platform.create_if_possible('some-platform', 'Some Platform')94 other_platform = Platform.create_if_possible('other-platform', 'Other Platform')95 Test.update_or_insert('some-test', webkit_trunk, some_platform)96 Test.update_or_insert('some-test', webkit_trunk, other_platform)97 self.assertEqual(DashboardJSONGenerator().value(), {98 'defaultBranch': 'WebKit trunk',99 'branchToId': {'WebKit trunk': webkit_trunk.id},100 'platformToId': {'Some Platform': some_platform.id, 'Other Platform': other_platform.id},101 'testToId': {'some-test': Test.get_by_key_name('some-test').id},102 })103 def test_value_with_hidden_platform_and_tesst(self):104 webkit_trunk = Branch.create_if_possible('webkit-trunk', 'WebKit trunk')105 some_platform = Platform.create_if_possible('some-platform', 'Some Platform')106 hidden_platform = Platform.create_if_possible('hidden-platform', 'Hidden Platform')107 hidden_platform.hidden = True108 hidden_platform.put()109 Test.update_or_insert('some-test', webkit_trunk, some_platform)110 Test.update_or_insert('some-test', webkit_trunk, hidden_platform)111 Test.update_or_insert('other-test', webkit_trunk, some_platform)112 Test.update_or_insert('other-test', webkit_trunk, hidden_platform)113 Test.update_or_insert('hidden-test', webkit_trunk, some_platform)114 Test.update_or_insert('hidden-test', webkit_trunk, hidden_platform)115 hidden_test = Test.get_by_key_name('hidden-test')116 hidden_test.hidden = True117 hidden_test.put()118 self.assertEqual(DashboardJSONGenerator().value()['platformToId'], {'Some Platform': some_platform.id})119 self.assertEqual(DashboardJSONGenerator().value()['testToId'],120 {'some-test': Test.get_by_key_name('some-test').id, 'other-test': Test.get_by_key_name('other-test').id})121class ManifestJSONGeneratorTest(DataStoreTestsBase):122 def test_value_no_branch(self):123 self.assertThereIsNoInstanceOf(Branch)124 self.assertEqual(ManifestJSONGenerator().value(), {'branchMap': {}, 'platformMap': {}, 'testMap': {}})125 def test_value_no_plaforms(self):126 some_branch = Branch.create_if_possible('some-branch', 'Some Branch')127 self.assertEqual(ManifestJSONGenerator().value(), {'branchMap': {}, 'platformMap': {}, 'testMap': {}})128 def _assert_single_test(self, value, branch, platform, test):129 self.assertEqualUnorderedList(value.keys(), ['branchMap', 'platformMap', 'testMap'])130 self.assertEqual(value['branchMap'],131 {branch.id: {'name': branch.name, 'testIds': [test.id], 'platformIds': [platform.id]}})132 self.assertEqual(value['platformMap'],133 {platform.id: {'name': platform.name, 'branchIds': [branch.id], 'testIds': [test.id]}})134 self.assertEqual(value['testMap'],135 {test.id: {'name': test.name, 'branchIds': [branch.id], 'platformIds': [platform.id]}})136 def test_value_single_platform(self):137 some_branch = Branch.create_if_possible('some-branch', 'Some Branch')138 some_platform = Platform.create_if_possible('some-platform', 'Some Platform')139 self.assertEqual(ManifestJSONGenerator().value(), {'branchMap': {}, 'platformMap': {}, 'testMap': {}})140 some_test = Test.update_or_insert('some-test', some_branch, some_platform)141 self._assert_single_test(ManifestJSONGenerator().value(), some_branch, some_platform, some_test)142 def test_value_two_platforms(self):143 some_branch = Branch.create_if_possible('some-branch', 'Some Branch')144 some_platform = Platform.create_if_possible('some-platform', 'Some Platform')145 other_platform = Platform.create_if_possible('other-platform', 'Other Platform')146 some_test = Test.update_or_insert('some-test', some_branch, some_platform)147 self._assert_single_test(ManifestJSONGenerator().value(), some_branch, some_platform, some_test)148 some_test = Test.update_or_insert('some-test', some_branch, other_platform)149 self.assertEqualUnorderedList(some_test.platforms, [some_platform.key(), other_platform.key()])150 value = ManifestJSONGenerator().value()151 expected_platform_ids = [some_platform.id, other_platform.id]152 self.assertEqualUnorderedList(value.keys(), ['branchMap', 'platformMap', 'testMap'])153 self.assertEqualUnorderedList(value['branchMap'],154 {some_branch.id: {'name': some_branch.name, 'testIds': [some_test.id], 'platformIds': expected_platform_ids}})155 self.assertEqual(value['platformMap'],156 {some_platform.id: {'name': some_platform.name, 'branchIds': [some_branch.id], 'testIds': [some_test.id]},157 other_platform.id: {'name': other_platform.name, 'branchIds': [some_branch.id], 'testIds': [some_test.id]}})158 self.assertEqual(value['testMap'],159 {some_test.id: {'name': some_test.name, 'branchIds': [some_branch.id], 'platformIds': expected_platform_ids}})160 def test_value_two_tests(self):161 some_branch = Branch.create_if_possible('some-branch', 'Some Branch')162 some_platform = Platform.create_if_possible('some-platform', 'Some Platform')163 some_test = Test.update_or_insert('some-test', some_branch, some_platform)164 self._assert_single_test(ManifestJSONGenerator().value(), some_branch, some_platform, some_test)165 other_test = Test.update_or_insert('other-test', some_branch, some_platform)166 value = ManifestJSONGenerator().value()167 expected_test_ids = [some_test.id, other_test.id]168 self.assertEqualUnorderedList(value.keys(), ['branchMap', 'platformMap', 'testMap'])169 self.assertEqual(value['branchMap'],170 {some_branch.id: {'name': some_branch.name, 'testIds': expected_test_ids, 'platformIds': [some_platform.id]}})171 self.assertEqual(value['platformMap'],172 {some_platform.id: {'name': some_platform.name, 'branchIds': [some_branch.id], 'testIds': expected_test_ids}})173 self.assertEqual(value['testMap'],174 {some_test.id: {'name': some_test.name, 'branchIds': [some_branch.id], 'platformIds': [some_platform.id]},175 other_test.id: {'name': other_test.name, 'branchIds': [some_branch.id], 'platformIds': [some_platform.id]}})176 def test_value_with_hidden_platform_and_test(self):177 some_branch = Branch.create_if_possible('some-branch', 'Some Branch')178 some_platform = Platform.create_if_possible('some-platform', 'Some Platform')179 hidden_platform = Platform.create_if_possible('hidden-platform', 'Hidden Platform')180 hidden_platform.hidden = True181 hidden_platform.put()182 Test.update_or_insert('some-test', some_branch, some_platform)183 some_test = Test.update_or_insert('some-test', some_branch, hidden_platform)184 Test.update_or_insert('hidden-test', some_branch, some_platform)185 hidden_test = Test.update_or_insert('hidden-test', some_branch, hidden_platform)186 hidden_test.hidden = True187 hidden_test.put()188 value = ManifestJSONGenerator().value()189 expected_test_ids = []190 self.assertEqualUnorderedList(value.keys(), ['branchMap', 'platformMap', 'testMap'])191 self.assertEqual(value['branchMap'],192 {some_branch.id: {'name': some_branch.name, 'testIds': [some_test.id], 'platformIds': [some_platform.id]}})193 self.assertEqual(value['platformMap'],194 {some_platform.id: {'name': some_platform.name, 'branchIds': [some_branch.id], 'testIds': [some_test.id]}})195 self.assertEqual(value['testMap'],196 {some_test.id: {'name': some_test.name, 'branchIds': [some_branch.id], 'platformIds': [some_platform.id]}})197if __name__ == '__main__':...

Full Screen

Full Screen

test_patcher.py

Source:test_patcher.py Github

copy

Full Screen

...65 test_called = False66 exc = Exception()67 68 @fudge.with_patched_object(holder, "exc", Freddie())69 def some_test():70 holder.test_called = True71 eq_(type(holder.exc), type(Freddie()))72 73 eq_(some_test.__name__, 'some_test')74 some_test()75 eq_(holder.test_called, True)76 eq_(type(holder.exc), type(Exception()))77def test_decorator_on_class():78 class holder:79 test_called = False80 exc = Exception()81 82 class SomeTest(object):83 84 @fudge.with_patched_object(holder, "exc", Freddie())85 def some_test(self):86 holder.test_called = True87 eq_(type(holder.exc), type(Freddie()))88 89 eq_(SomeTest.some_test.__name__, 'some_test')90 s = SomeTest()91 s.some_test()92 eq_(holder.test_called, True)93 eq_(type(holder.exc), type(Exception()))94def test_patched_context():95 if not hasattr(fudge, "patched_context"):96 raise SkipTest("Cannot test with patched_context() because not in 2.5")97 98 class Boo:99 fargo = "is over there"100 101 ctx = fudge.patched_context(Boo, 'fargo', 'is right here')102 # simulate with fudge.patched_context():103 ctx.__enter__()104 eq_(Boo.fargo, "is right here")105 ctx.__exit__(None, None, None)106 eq_(Boo.fargo, "is over there")107def test_base_class_attribute():108 class Base(object):109 foo = 'bar'110 class Main(Base):111 pass112 fake = fudge.Fake()113 p = fudge.patch_object(Main, 'foo', fake)114 eq_(Main.foo, fake)115 eq_(Base.foo, 'bar')116 p.restore()117 eq_(Main.foo, 'bar')118 assert 'foo' not in Main.__dict__, ('Main.foo was not restored correctly')119def test_bound_methods():120 class Klass(object):121 def method(self):122 return 'foozilate'123 instance = Klass()124 fake = fudge.Fake()125 p = fudge.patch_object(instance, 'method', fake)126 eq_(instance.method, fake)127 p.restore()128 eq_(instance.method(), Klass().method())129 assert inspect.ismethod(instance.method)130 assert 'method' not in instance.__dict__, (131 'instance.method was not restored correctly')132def test_staticmethod_descriptor():133 class Klass(object):134 @staticmethod135 def static():136 return 'OK'137 fake = fudge.Fake()138 p = fudge.patch_object(Klass, 'static', fake)139 eq_(Klass.static, fake)140 p.restore()141 eq_(Klass.static(), 'OK')142def test_property():143 class Klass(object):144 @property145 def prop(self):146 return 'OK'147 exact_prop = Klass.prop148 instance = Klass()149 fake = fudge.Fake()150 p = fudge.patch_object(instance, 'prop', fake)151 eq_(instance.prop, fake)152 p.restore()153 eq_(instance.prop, 'OK')154 eq_(Klass.prop, exact_prop)155def test_inherited_property():156 class SubKlass(object):157 @property158 def prop(self):159 return 'OK'160 class Klass(SubKlass):161 pass162 exact_prop = SubKlass.prop163 instance = Klass()164 fake = fudge.Fake()165 p = fudge.patch_object(instance, 'prop', fake)166 eq_(instance.prop, fake)167 p.restore()168 eq_(instance.prop, 'OK')169 assert 'prop' not in Klass.__dict__, (170 'Klass.prop was not restored properly')171 eq_(SubKlass.prop, exact_prop)172class TestPatch(unittest.TestCase):173 def setUp(self):174 fudge.clear_expectations()175 def test_decorator_on_def(self):176 class holder:177 test_called = False178 179 @fudge.patch('shutil.copy')180 def some_test(copy):181 import shutil182 holder.test_called = True183 assert isinstance(copy, fudge.Fake)184 eq_(copy, shutil.copy)185 186 eq_(some_test.__name__, 'some_test')187 some_test()188 eq_(holder.test_called, True)189 import shutil190 assert not isinstance(shutil.copy, fudge.Fake)191 def test_decorator_on_class(self):192 class holder:193 test_called = False194 195 class MyTest(object):196 @fudge.patch('shutil.copy')197 def some_test(self, copy):198 import shutil199 holder.test_called = True200 assert isinstance(copy, fudge.Fake)201 eq_(copy, shutil.copy)202 203 eq_(MyTest.some_test.__name__, 'some_test')204 m = MyTest()205 m.some_test()206 eq_(holder.test_called, True)207 import shutil208 assert not isinstance(shutil.copy, fudge.Fake)209 def test_patch_many(self):210 class holder:211 test_called = False212 213 @fudge.patch('shutil.copy',214 'os.remove')215 def some_test(copy, remove):216 import shutil217 import os218 holder.test_called = True219 assert isinstance(copy, fudge.Fake)220 assert isinstance(remove, fudge.Fake)221 eq_(copy, shutil.copy)222 eq_(remove, os.remove)223 224 eq_(some_test.__name__, 'some_test')225 some_test()226 eq_(holder.test_called, True)227 import shutil228 assert not isinstance(shutil.copy, fudge.Fake)229 import os230 assert not isinstance(os.remove, fudge.Fake)231 def test_with_patch(self):232 class holder:233 test_called = False234 def run_test():235 with fudge.patch('shutil.copy') as copy:236 import shutil237 assert isinstance(copy, fudge.Fake)238 eq_(copy, shutil.copy)239 holder.test_called = True...

Full Screen

Full Screen

3899.py

Source:3899.py Github

copy

Full Screen

...107def test_trigger_arg():108 """test event triggering with arguments"""109 obs = Observable()110 @obs.on("some_test")111 def some_test(some_data):112 assert some_data == "some data"113 assert obs.trigger("some_test", "some data")114def test_trigger_args():115 """test event triggering with argument list"""116 obs = Observable()117 @obs.on("some_test")118 def some_test(some_data, some_other_data):119 assert some_data is True120 assert some_other_data is False121 assert obs.trigger("some_test", *[True, False])122def test_trigger_kwargs():123 """test event triggering with keyword-arguments"""124 obs = Observable()125 @obs.on("some_test")126 def some_test(some_data=True, some_other_data=False):127 assert some_data is False128 assert some_other_data is True129 assert obs.trigger("some_test", some_other_data=True, some_data=False)130def test_on_multiple_handlers():131 """test event registering with the on method and multiple handlers"""132 obs = Observable()133 results = []134 def some_test(*args, **kw):135 results.append(1)136 def some_test_2(*args, **kw):137 results.append(2)138 obs.on("some_test", some_test, some_test_2)139 assert len(obs._events["some_test"]) == 2140 obs.trigger("some_test")141 assert results == [1, 2]142def test_off_multiple_handlers():143 """test event unregistering with the off method and multiple handlers"""144 obs = Observable()145 results = []146 def some_test(*args, **kw):147 results.append(1)148 def some_test_2(*args, **kw):149 results.append(2)150 obs.on("some_test", some_test, some_test_2)151 assert len(obs._events["some_test"]) == 2152 obs.off("some_test", some_test, some_test_2)153 assert len(obs._events["some_test"]) == 0154 assert not obs.trigger("some_test")155def test_multiple_inheritance():156 """Test using class inheritance without calling Observable.__init__"""157 class SomeBaseClass(object):158 pass159 class SomeBaseAndObservable(SomeBaseClass, Observable):160 def __init__(self):161 super(SomeBaseAndObservable, self).__init__()162 def test(self):163 self.trigger("some", True)164 def some_test(data):165 assert data is True166 obj = SomeBaseAndObservable()167 obj.on("some", some_test)168 obj.test()169def test_get_all_handlers():170 """test get_all_handlers() after registering handlers for two events"""171 obs = Observable()172 def some_test():173 pass174 def other_test():175 pass176 assert not obs.get_all_handlers()177 obs.on("some_event", some_test)178 assert "some_event" in obs.get_all_handlers()179 assert some_test in obs.get_all_handlers()["some_event"]180 obs.on("other_event", other_test)181 assert "other_event" in obs.get_all_handlers()182 assert other_test in obs.get_all_handlers()["other_event"]183 assert other_test not in obs.get_all_handlers()["some_event"]184def test_get_handlers():185 """test get_handlers() after registering handlers for two events"""186 obs = Observable()187 def some_test():188 pass189 def other_test():190 pass191 assert not obs.get_handlers("some_event")192 obs.on("some_event", some_test)193 assert some_test in obs.get_handlers("some_event")194 obs.on("other_event", other_test)195 assert other_test in obs.get_handlers("other_event")196 assert other_test not in obs.get_handlers("some_event")197def test_is_registered():198 """test is_registered() after registering an event"""199 obs = Observable()200 def some_test():201 pass202 assert not obs.is_registered("some_event", some_test)203 obs.on("some_event", some_test)...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Nose automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful