Best Python code snippet using Testify_python
list_tests_test.py
Source:list_tests_test.py  
1# Copyright 2015 The Chromium Authors. All rights reserved.2# Use of this source code is governed by a BSD-style license that can be3# found in the LICENSE file.4from __future__ import print_function5from __future__ import division6from __future__ import absolute_import7import json8import unittest9import webapp210import webtest11from google.appengine.ext import ndb12from dashboard import list_tests13from dashboard.common import datastore_hooks14from dashboard.common import layered_cache15from dashboard.common import testing_common16from dashboard.common import utils17from dashboard.models import graph_data18from dashboard.models import sheriff19class ListTestsTest(testing_common.TestCase):20  def setUp(self):21    super(ListTestsTest, self).setUp()22    app = webapp2.WSGIApplication(23        [('/list_tests', list_tests.ListTestsHandler)])24    self.testapp = webtest.TestApp(app)25    datastore_hooks.InstallHooks()26    self.UnsetCurrentUser()27    testing_common.SetIsInternalUser('internal@chromium.org', True)28    testing_common.SetIsInternalUser('foo@chromium.org', False)29  def _AddSampleData(self):30    testing_common.AddTests(31        ['Chromium'],32        ['win7', 'mac'],33        {34            'dromaeo': {35                'dom': {},36                'jslib': {},37            },38            'scrolling': {39                'commit_time': {40                    'www.alibaba.com': {},41                    'www.yahoo.com': {},42                    'www.cnn.com': {},43                },44                'commit_time_ref': {},45            },46            'really': {47                'nested': {48                    'very': {49                        'deeply': {50                            'subtest': {}51                        }52                    },53                    'very_very': {}54                }55            },56        })57  def testPost_GetTestsForTestPath_Selected_Invalid(self):58    self._AddSampleData()59    # Requesting an invalid test path should not throw 500 error, it should60    # silently ignore the requested invalid test path.61    response = self.testapp.post('/list_tests', {62        'type': 'test_path_dict',63        'test_path_dict': json.dumps({64            'Chromium/win7/scrolling/commit_time': ['commit_time_ref']}),65        'return_selected': '1'})66    expected = {'anyMissing': True, 'tests': []}67    self.assertEqual(expected, json.loads(response.body))68  def testGetSubTests_FetchAndCacheBehavior(self):69    self._AddSampleData()70    # Set the has_rows flag to true on two of the TestMetadata entities.71    for test_path in [72        'Chromium/win7/really/nested/very/deeply/subtest',73        'Chromium/win7/really/nested/very_very']:74      test = utils.TestKey(test_path).get()75      test.has_rows = True76      test.put()77    # A tree-structured dict of dicts is constructed, and the 'has_rows'78    # flag is set to true for two of these tests. These two tests and79    # their parents are all included in the result.80    response = self.testapp.post('/list_tests', {81        'type': 'sub_tests',82        'suite': 'really',83        'bots': 'Chromium/win7,Chromium/mac'})84    self.assertEqual('*', response.headers.get('Access-Control-Allow-Origin'))85    expected = {86        'nested': {87            'has_rows': False,88            'sub_tests': {89                'very': {90                    'has_rows': False,91                    'sub_tests': {92                        'deeply': {93                            'has_rows': False,94                            'sub_tests': {95                                'subtest': {96                                    'has_rows': True,97                                    'sub_tests': {}98                                }99                            }100                        }101                    }102                },103                'very_very': {104                    'has_rows': True,105                    'sub_tests': {}106                }107            }108        }109    }110    # The response should be as expected.111    self.assertEqual(expected, json.loads(response.body))112    # The cache should be set for the win7 bot with the expected response.113    self.assertEqual(expected, json.loads(layered_cache.Get(114        graph_data.LIST_TESTS_SUBTEST_CACHE_KEY % (115            'Chromium', 'win7', 'really'))))116    # Change mac subtests in cache. Should be merged with win7.117    mac_subtests = {118        'mactest': {119            'has_rows': False,120            'sub_tests': {121                'graph': {122                    'has_rows': True,123                    'sub_tests': {}124                }125            }126        }127    }128    layered_cache.Set(129        graph_data.LIST_TESTS_SUBTEST_CACHE_KEY % ('Chromium', 'mac', 'really'),130        json.dumps(mac_subtests))131    response = self.testapp.post('/list_tests', {132        'type': 'sub_tests',133        'suite': 'really',134        'bots': 'Chromium/win7,Chromium/mac'})135    self.assertEqual('*', response.headers.get('Access-Control-Allow-Origin'))136    expected.update(mac_subtests)137    self.assertEqual(expected, json.loads(response.body))138  def testGetSubTests_ReturnsOnlyNonDeprecatedTests(self):139    # Sub-tests with the same name may be deprecated on only one bot, and not140    # deprecated on another bot; only non-deprecated tests should be returned.141    self._AddSampleData()142    # Set the deprecated flag to True for one test on one platform.143    test = utils.TestKey('Chromium/mac/dromaeo/jslib').get()144    test.deprecated = True145    test.put()146    # Set the has_rows flag to true for all of the test entities.147    for test_path in [148        'Chromium/win7/dromaeo/dom',149        'Chromium/win7/dromaeo/jslib',150        'Chromium/mac/dromaeo/dom',151        'Chromium/mac/dromaeo/jslib']:152      test = utils.TestKey(test_path).get()153      test.has_rows = True154      test.put()155    # When a request is made for subtests for the platform wherein that a156    # subtest is deprecated, that subtest will not be listed.157    response = self.testapp.post('/list_tests', {158        'type': 'sub_tests',159        'suite': 'dromaeo',160        'bots': 'Chromium/mac'})161    self.assertEqual('*', response.headers.get('Access-Control-Allow-Origin'))162    expected = {163        'dom': {164            'has_rows': True,165            'sub_tests': {}166        },167        'jslib': {168            'has_rows': True,169            'sub_tests': {},170            'deprecated': True171        }172    }173    self.assertEqual(expected, json.loads(response.body))174  def testPost_GetTestsForTestPath_Selected_SomeInternal(self):175    self._AddSampleData()176    # Set has_rows on two subtests but internal_only on only one.177    test = graph_data.TestMetadata.get_by_id(178        'Chromium/win7/scrolling/commit_time/www.cnn.com')179    test.internal_only = True180    test.has_rows = True181    test.put()182    test = graph_data.TestMetadata.get_by_id(183        'Chromium/win7/scrolling/commit_time/www.yahoo.com')184    test.has_rows = True185    test.put()186    request = {187        'type': 'test_path_dict',188        'test_path_dict': json.dumps({189            'Chromium/win7/scrolling/commit_time': [190                'www.cnn.com', 'www.yahoo.com']}),191        'return_selected': '1',192    }193    self.SetCurrentUser('internal@chromium.org')194    response = self.testapp.post('/list_tests', request)195    expected = {196        'anyMissing': False,197        'tests': [198            'Chromium/win7/scrolling/commit_time/www.cnn.com',199            'Chromium/win7/scrolling/commit_time/www.yahoo.com',200        ],201    }202    self.assertEqual(expected, json.loads(response.body))203    self.SetCurrentUser('foo@chromium.org')204    response = self.testapp.post('/list_tests', request)205    expected = {206        'anyMissing': True,207        'tests': [208            'Chromium/win7/scrolling/commit_time/www.yahoo.com',209        ],210    }211    self.assertEqual(expected, json.loads(response.body))212  def testGetSubTests_InternalData_OnlyReturnedForAuthorizedUsers(self):213    # When the user has a an internal account, internal-only data is given.214    self.SetCurrentUser('internal@chromium.org')215    self._AddSampleData()216    # Set internal_only on a bot and top-level test.217    bot = ndb.Key('Master', 'Chromium', 'Bot', 'win7').get()218    bot.internal_only = True219    bot.put()220    test = graph_data.TestMetadata.get_by_id('Chromium/win7/dromaeo')221    test.internal_only = True222    test.put()223    # Set internal_only and has_rows to true on two subtests.224    for name in ['dom', 'jslib']:225      subtest = graph_data.TestMetadata.get_by_id(226          'Chromium/win7/dromaeo/%s' % name)227      subtest.internal_only = True228      subtest.has_rows = True229      subtest.put()230    # All of the internal-only tests are returned.231    response = self.testapp.post('/list_tests', {232        'type': 'sub_tests', 'suite': 'dromaeo', 'bots': 'Chromium/win7'})233    expected = {234        'dom': {235            'has_rows': True,236            'sub_tests': {}237        },238        'jslib': {239            'has_rows': True,240            'sub_tests': {}241        }242    }243    self.assertEqual(expected, json.loads(response.body))244    # After setting the user to another domain, an empty dict is returned.245    self.SetCurrentUser('foo@chromium.org')246    response = self.testapp.post('/list_tests', {247        'type': 'sub_tests', 'suite': 'dromaeo', 'bots': 'Chromium/win7'})248    self.assertEqual({}, json.loads(response.body))249  def testMergeSubTestsDict(self):250    a = {251        'foo': {252            'has_rows': True,253            'sub_tests': {'a': {'has_rows': True, 'sub_tests': {}}},254        },255        'bar': {256            'has_rows': False,257            'sub_tests': {258                'b': {259                    'has_rows': False,260                    'sub_tests': {261                        'c': {262                            'has_rows': False,263                            'deprecated': True,264                            'sub_tests': {},265                        },266                    },267                },268            },269        },270    }271    b = {272        'bar': {273            'has_rows': True,274            'sub_tests': {275                'b': {276                    'has_rows': False,277                    'sub_tests': {278                        'c': {279                            'has_rows': False,280                            'sub_tests': {},281                        },282                    },283                },284            },285        },286        'baz': {'has_rows': False, 'sub_tests': {}},287    }288    self.assertEqual(289        {290            'foo': {291                'has_rows': True,292                'sub_tests': {'a': {'has_rows': True, 'sub_tests': {}}},293            },294            'bar': {295                'has_rows': True,296                'sub_tests': {297                    'b': {298                        'has_rows': False,299                        'sub_tests': {300                            'c': {'has_rows': False, 'sub_tests': {}},301                        },302                    },303                },304            },305            'baz': {'has_rows': False, 'sub_tests': {}},306        },307        list_tests._MergeSubTestsDict(a, b))308  def testSubTestsDict(self):309    paths = [310        ['a', 'b', 'c'],311        ['a', 'b', 'c'],312        ['a', 'b', 'd'],313    ]314    expected = {315        'a': {316            'has_rows': False,317            'sub_tests': {318                'b': {319                    'has_rows': False,320                    'sub_tests': {321                        'c': {'has_rows': True, 'sub_tests': {}},322                        'd': {'has_rows': True, 'sub_tests': {}},323                    },324                },325            },326        },327    }328    self.assertEqual(329        expected, list_tests._SubTestsDict(paths, False))330  def testSubTestsDict_Deprecated(self):331    paths = [332        ['a'],333        ['a', 'b'],334    ]335    expected = {336        'a': {337            'has_rows': True,338            'deprecated': True,339            'sub_tests': {340                'b': {341                    'has_rows': True,342                    'deprecated': True,343                    'sub_tests': {},344                },345            },346        },347    }348    self.assertEqual(349        expected, list_tests._SubTestsDict(paths, True))350  def testSubTestsDict_TopLevel_HasRows_False(self):351    paths = [352        ['a', 'b'],353        ['a', 'c'],354    ]355    expected = {356        'a': {357            'has_rows': False,358            'sub_tests': {359                'b': {'has_rows': True, 'sub_tests': {}},360                'c': {'has_rows': True, 'sub_tests': {}},361            },362        },363    }364    self.assertEqual(365        expected, list_tests._SubTestsDict(paths, False))366  def testSubTestsDict_RepeatedPathIgnored(self):367    paths = [368        ['a', 'b'],369        ['a', 'c'],370        ['a', 'b'],371    ]372    expected = {373        'a': {374            'has_rows': False,375            'sub_tests': {376                'b': {'has_rows': True, 'sub_tests': {}},377                'c': {'has_rows': True, 'sub_tests': {}},378            },379        },380    }381    self.assertEqual(382        expected, list_tests._SubTestsDict(paths, False))383  def testPost_GetTestsMatchingPattern(self):384    """Tests the basic functionality of the GetTestsMatchingPattern function."""385    self._AddSampleData()386    # A pattern can match tests with a particular bot and with a particular387    # number of levels of nesting.388    # The results are lexicographically ordered by test path.389    response = self.testapp.post('/list_tests', {390        'type': 'pattern',391        'p': 'Chromium/mac/*/*/www*'})392    expected = [393        'Chromium/mac/scrolling/commit_time/www.alibaba.com',394        'Chromium/mac/scrolling/commit_time/www.cnn.com',395        'Chromium/mac/scrolling/commit_time/www.yahoo.com',396    ]397    self.assertEqual(expected, json.loads(response.body))398    # The same thing is returned if has_rows is set to '0' or another string399    # that is not '1'.400    response = self.testapp.post('/list_tests', {401        'type': 'pattern',402        'has_rows': '0',403        'p': '*/mac/*/*/www*'})404    self.assertEqual(expected, json.loads(response.body))405    response = self.testapp.post('/list_tests', {406        'type': 'pattern',407        'has_rows': 'foo',408        'p': '*/mac/*/*/www*'})409    self.assertEqual(expected, json.loads(response.body))410  def testPost_GetTestsMatchingPattern_OnlyWithRows(self):411    """Tests GetTestsMatchingPattern with the parameter only_with_rows set."""412    self._AddSampleData()413    # When no TestMetadata entities have has_rows set, filtering with the414    # parameter 'has_rows' set to '1' results in no rows being returned.415    response = self.testapp.post('/list_tests', {416        'type': 'pattern',417        'has_rows': '1',418        'p': '*/mac/dromaeo/*'})419    self.assertEqual([], json.loads(response.body))420    # Set the has_rows flag on one of the tests.421    test = utils.TestKey('Chromium/mac/dromaeo/dom').get()422    test.has_rows = True423    test.put()424    # Even though multiple tests could match the pattern, only the test with425    # has_rows set is returned.426    response = self.testapp.post('/list_tests', {427        'type': 'pattern',428        'has_rows': '1',429        'p': '*/mac/dromaeo/*'})430    self.assertEqual(['Chromium/mac/dromaeo/dom'], json.loads(response.body))431  def testPost_GetTestsForTestPath_Selected_Core_MonitoredChildWithRows(self):432    yahoo_path = 'Chromium/win7/scrolling/commit_time/www.yahoo.com'433    sheriff.Sheriff(434        id='my_sheriff1', email='a@chromium.org', patterns=[yahoo_path]).put()435    self._AddSampleData()436    yahoo = graph_data.TestMetadata.get_by_id(yahoo_path)437    yahoo.has_rows = True438    yahoo.put()439    response = self.testapp.post('/list_tests', {440        'type': 'test_path_dict',441        'test_path_dict': json.dumps({442            'Chromium/win7/scrolling/commit_time': 'core'}),443        'return_selected': '1'})444    expected = {445        'anyMissing': False,446        'tests': ['Chromium/win7/scrolling/commit_time/www.yahoo.com'],447    }448    self.assertEqual(expected, json.loads(response.body))449  def testPost_GetTestsForTestPath_Selected_Core_MonitoredChildNoRows(self):450    self._AddSampleData()451    response = self.testapp.post('/list_tests', {452        'type': 'test_path_dict',453        'test_path_dict': json.dumps({454            'Chromium/win7/scrolling/commit_time': 'core'}),455        'return_selected': '1'})456    expected = {'tests': [], 'anyMissing': False}457    self.assertEqual(expected, json.loads(response.body))458  def testPost_GetTestsForTestPath_Selected_Core_ParentHasRows(self):459    self._AddSampleData()460    core = graph_data.TestMetadata.get_by_id(461        'Chromium/win7/scrolling/commit_time')462    core.has_rows = True463    core.put()464    response = self.testapp.post('/list_tests', {465        'type': 'test_path_dict',466        'test_path_dict': json.dumps({467            'Chromium/win7/scrolling/commit_time': 'core'}),468        'return_selected': '1'})469    expected = {470        'anyMissing': False,471        'tests': ['Chromium/win7/scrolling/commit_time'],472    }473    self.assertEqual(expected, json.loads(response.body))474  def testPost_GetTestsForTestPath_Selected_Core_AllHaveRows(self):475    yahoo_path = 'Chromium/win7/scrolling/commit_time/www.yahoo.com'476    sheriff.Sheriff(477        id='my_sheriff1', email='a@chromium.org', patterns=[yahoo_path]).put()478    self._AddSampleData()479    core = graph_data.TestMetadata.get_by_id(480        'Chromium/win7/scrolling/commit_time')481    core.has_rows = True482    core.put()483    yahoo = graph_data.TestMetadata.get_by_id(yahoo_path)484    yahoo.has_rows = True485    yahoo.put()486    response = self.testapp.post('/list_tests', {487        'type': 'test_path_dict',488        'test_path_dict': json.dumps({489            'Chromium/win7/scrolling/commit_time': 'core'}),490        'return_selected': '1'})491    expected = {492        'anyMissing': False,493        'tests': [494            'Chromium/win7/scrolling/commit_time',495            'Chromium/win7/scrolling/commit_time/www.yahoo.com',496        ],497    }498    self.assertEqual(expected, json.loads(response.body))499  def testPost_GetTestsForTestPath_Selected_Core_NoRows(self):500    self._AddSampleData()501    response = self.testapp.post('/list_tests', {502        'type': 'test_path_dict',503        'test_path_dict': json.dumps({504            'Chromium/win7/scrolling/commit_time': 'core'}),505        'return_selected': '1'})506    expected = {507        'anyMissing': False,508        'tests': [],509    }510    self.assertEqual(expected, json.loads(response.body))511  def testPost_GetTestsForTestPath_Selected_EmptyPreselected(self):512    self._AddSampleData()513    response = self.testapp.post('/list_tests', {514        'type': 'test_path_dict',515        'test_path_dict': json.dumps({516            'Chromium/win7/scrolling/commit_time': []}),517        'return_selected': '1'})518    expected = {'anyMissing': False, 'tests': []}519    self.assertEqual(expected, json.loads(response.body))520  def testPost_GetTestsForTestPath_Selected_Preselected(self):521    self._AddSampleData()522    test = utils.TestKey(523        'Chromium/win7/scrolling/commit_time/www.yahoo.com').get()524    test.has_rows = True525    test.put()526    response = self.testapp.post('/list_tests', {527        'type': 'test_path_dict',528        'test_path_dict': json.dumps({529            'Chromium/win7/scrolling/commit_time': [530                'commit_time', 'www.yahoo.com']}),531        'return_selected': '1'})532    expected = {533        'anyMissing': True,534        'tests': ['Chromium/win7/scrolling/commit_time/www.yahoo.com'],535    }536    self.assertEqual(expected, json.loads(response.body))537  def testPost_GetTestsForTestPath_Selected_Preselected_Multiple(self):538    self._AddSampleData()539    subtest = graph_data.TestMetadata.get_by_id(540        'Chromium/win7/scrolling/commit_time/www.cnn.com')541    subtest.has_rows = True542    subtest.put()543    subtest = graph_data.TestMetadata.get_by_id(544        'Chromium/mac/scrolling/commit_time/www.cnn.com')545    subtest.has_rows = True546    subtest.put()547    response = self.testapp.post('/list_tests', {548        'type': 'test_path_dict',549        'test_path_dict': json.dumps({550            'Chromium/win7/scrolling/commit_time': ['www.cnn.com'],551            'Chromium/mac/scrolling/commit_time': ['www.cnn.com']}),552        'return_selected': '1'})553    expected = {554        'anyMissing': False,555        'tests': [556            'Chromium/win7/scrolling/commit_time/www.cnn.com',557            'Chromium/mac/scrolling/commit_time/www.cnn.com'],558    }559    self.assertEqual(expected, json.loads(response.body))560  def testPost_GetTestsForTestPath_Selected_All(self):561    self._AddSampleData()562    subtest = graph_data.TestMetadata.get_by_id(563        'Chromium/win7/scrolling/commit_time/www.cnn.com')564    subtest.has_rows = True565    subtest.put()566    response = self.testapp.post('/list_tests', {567        'type': 'test_path_dict',568        'test_path_dict': json.dumps({569            'Chromium/win7/scrolling/commit_time': 'all'}),570        'return_selected': '1'})571    expected = {572        'anyMissing': True,573        'tests': ['Chromium/win7/scrolling/commit_time/www.cnn.com'],574    }575    self.assertEqual(expected, json.loads(response.body))576  def testPost_GetTestsForTestPath_Unselected_Core_NoParent(self):577    self._AddSampleData()578    response = self.testapp.post('/list_tests', {579        'type': 'test_path_dict',580        'test_path_dict': json.dumps({581            'Chromium/win7/scrolling/commit_time': 'core'}),582        'return_selected': '0'})583    expected = {'tests': []}584    self.assertEqual(expected, json.loads(response.body))585  def testPost_GetTestsForTestPath_Unselected_Core_Unmonitored(self):586    yahoo_path = 'Chromium/win7/scrolling/commit_time/www.yahoo.com'587    sheriff.Sheriff(588        id='my_sheriff1', email='a@chromium.org', patterns=[yahoo_path]).put()589    self._AddSampleData()590    cnn = graph_data.TestMetadata.get_by_id(591        'Chromium/win7/scrolling/commit_time/www.cnn.com')592    cnn.has_rows = True593    cnn.put()594    yahoo = graph_data.TestMetadata.get_by_id(yahoo_path)595    yahoo.has_rows = True596    yahoo.put()597    response = self.testapp.post('/list_tests', {598        'type': 'test_path_dict',599        'test_path_dict': json.dumps({600            'Chromium/win7/scrolling/commit_time': 'core'}),601        'return_selected': '0'})602    expected = {603        'tests': ['Chromium/win7/scrolling/commit_time/www.cnn.com'],604    }605    self.assertEqual(expected, json.loads(response.body))606  def testPost_GetTestsForTestPath_Unselected_EmptyPreselected(self):607    self._AddSampleData()608    response = self.testapp.post('/list_tests', {609        'type': 'test_path_dict',610        'test_path_dict': json.dumps({611            'Chromium/win7/scrolling/commit_time': []}),612        'return_selected': '0'})613    expected = {614        'tests': ['Chromium/win7/scrolling/commit_time'],615    }616    self.assertEqual(expected, json.loads(response.body))617  def testPost_GetTestsForTestPath_Unselected_PreselectedWithRows(self):618    self._AddSampleData()619    subtest = graph_data.TestMetadata.get_by_id(620        'Chromium/win7/scrolling/commit_time/www.cnn.com')621    subtest.has_rows = True622    subtest.put()623    response = self.testapp.post('/list_tests', {624        'type': 'test_path_dict',625        'test_path_dict': json.dumps({626            'Chromium/win7/scrolling/commit_time': [627                'commit_time', 'www.yahoo.com']}),628        'return_selected': '0'})629    expected = {630        'tests': ['Chromium/win7/scrolling/commit_time/www.cnn.com'],631    }632    self.assertEqual(expected, json.loads(response.body))633  def testPost_GetTestsForTestPath_Unselected_PreselectedWithoutRows(self):634    self._AddSampleData()635    response = self.testapp.post('/list_tests', {636        'type': 'test_path_dict',637        'test_path_dict': json.dumps({638            'Chromium/win7/scrolling/commit_time': [639                'commit_time', 'www.yahoo.com']}),640        'return_selected': '0'})641    expected = {'tests': []}642    self.assertEqual(expected, json.loads(response.body))643  def testPost_GetTestsForTestPath_Unselected_All(self):644    self._AddSampleData()645    response = self.testapp.post('/list_tests', {646        'type': 'test_path_dict',647        'test_path_dict': json.dumps({648            'Chromium/win7/scrolling/commit_time': 'all'}),649        'return_selected': '0'})650    self.assertEqual({'tests': []}, json.loads(response.body))651  def testGetDescendants(self):652    self._AddSampleData()653    self.assertEqual(654        list_tests.GetTestDescendants(655            ndb.Key('TestMetadata', 'Chromium/mac/dromaeo')), [656                ndb.Key('TestMetadata', 'Chromium/mac/dromaeo'),657                ndb.Key('TestMetadata', 'Chromium/mac/dromaeo/dom'),658                ndb.Key('TestMetadata', 'Chromium/mac/dromaeo/jslib'),])659    self.assertEqual(660        list_tests.GetTestDescendants(661            ndb.Key('TestMetadata', 'Chromium/win7/really/nested')), [662                ndb.Key('TestMetadata', 'Chromium/win7/really/nested'),663                ndb.Key('TestMetadata', 'Chromium/win7/really/nested/very'),664                ndb.Key('TestMetadata',665                        'Chromium/win7/really/nested/very/deeply'),666                ndb.Key('TestMetadata',667                        'Chromium/win7/really/nested/very/deeply/subtest'),668                ndb.Key('TestMetadata',669                        'Chromium/win7/really/nested/very_very'),])670if __name__ == '__main__':...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.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
