How to use token_generator method in localstack

Best Python code snippet using localstack_python

parser.py

Source:parser.py Github

copy

Full Screen

1from io_lib import err, out_var, out_proc, debug2import table3__author__ = 'ay27'4'''5文法 字母表示 消除左递归等6<程序>→<分程序> S->T 删去7<分程序>→begin <说明语句表>;<执行语句表> end T->begin H;E end S-> begin H;E end8<说明语句表>→<说明语句>│<说明语句表> ;<说明语句> H->A|H;A H->AH' H'->;AH'|e9<说明语句>→<变量说明>│<函数说明> A->V|F A->integer D | integer function D(D);S10<变量说明>→integer <变量> V->integer C V->integer D11<变量>→<标识符> C->D 删去12<标识符>→<字母>│<标识符><字母>│ <标识符><数字> D->G|DG|DN D->GD' D'->GD'|ND'|e13<字母>→a│b│c│d│e│f│g│h│i│j│k│l│m│n│o │p│q │r│s│t│u│v│w│x│y│z G->a|b|c....14<数字>→0│1│2│3│4│5│6│7│8│9 N->0|1|2...15<函数说明>→integer function <标识符>(<参数>);<函数体> F->integer function D(M);S16<参数>→<变量> M->C17<函数体>→begin <说明语句表>;<执行语句表> end S->begin H;E end18<执行语句表>→<执行语句>│<执行语句表>;<执行语句> E->B|E;B E->BE' E'->;BE'|e19<执行语句>→<读语句>│<写语句>│<赋值语句>│<条件语句> B->R|W|Z|I20<读语句>→read(<变量>) R->read(C) R->read(D)21<写语句>→write(<变量>) W->write(C) W->write(D)22<赋值语句>→<变量>:=<算术表达式> Z->C:=K Z->D:=K23<算术表达式>→<算术表达式>-<项>│<项> K->K-L|L K->LK' K'=-LK'|e24<项>→<项>*<因子>│<因子> L->L*Y|Y L->YL' L'->*YL'|e25<因子>→<变量>│<常数>│<函数调用> Y->C|O|P Y->D|Q|P26<常数>→<无符号整数> O->Q 删去27<无符号整数>→<数字>│<无符号整数><数字> Q->N|QN Q->NQ' Q'->NQ'|e28<函数调用>→<标识符>(<参数>) P->D(M)29<条件语句>→if<条件表达式>then<执行语句>else <执行语句> I->if U then B else B30<条件表达式>→<算术表达式><关系运算符><算术表达式> U->KVK31<关系运算符> →<│<=│>│>=│=│<> V-><|<=|...32完整的文法如下:331. S->begin HE end 更改:去掉分号342. H->integer V;H' 更改:添上分号353. H'->integer V;H'|e 更改:天上那个分号36# 4. A->integer V374. V->D|function D(M);S385. D->GD'396. D'->GD'|ND'|e407. G->a|b|c....418. N->0|1|2...429. M->D4310. E->BE'4411. E'->;BE'|e4512. B->read(D)|write(D)|if U then B else B|Z4613. Z->D:=K4714. K->LK'4815. K'=-LK'|e4916. L->YL'5017. L'->*YL'|e5118. Y->D|Q|P 更改为:Y->GD'|NQ'|D(M)5219. Q->NQ'5320. Q'->NQ'|e5421. P->D(M) 更改:删去5522. U->KOK5623. O-><|<=|=...57'''58class Variable(object):59 """60 变量名vname: char(16)61 所属过程vproc:char(16)62 分类vkind: 0..1(0—变量、1—形参)63 变量类型vtype: types64 变量层次vlev: int65 变量在变量表中的位置vadr: int(相对第一个变量而言)66 types=(ints)67 """68 def __init__(self, vname, vproc, vkind, vtype, vlen, vadr):69 self.vname = vname70 self.vproc = vproc71 self.vkind = vkind72 self.vtype = vtype73 self.vlen = vlen74 self.vadr = vadr75 def __repr__(self):76 return '%s %s %d %s %d %d' % (self.vname, self.vproc, self.vkind, self.vtype, self.vlen, self.vadr)77class Proc(object):78 """79 过程名pname: char(16)80 过程类型ptype: types81 过程层次plev: int82 第一个变量在变量表中的位置fadr: int83 最后一个变量在变量表中的位置ladr: int84 """85 def __init__(self, pname, ptype, plev):86 self.pname = pname87 self.ptype = ptype88 self.plev = plev89 self.fadr = -190 self.ladr = -191 self.adr = len(proc_table)92 def __repr__(self):93 return '%s %s %d %d %d' % (self.pname, self.ptype, self.plev, self.fadr, self.ladr)94var_table = []95proc_table = []96plevel = 097current_proc = None98current_token = None99current_const = None100line_no = 1101def is_var_exist(token, proc, kind, expected=False):102 """103 在以下场合需要验证变量是否存在:104 1. 引入变量时需要检查是否已定义105 2. 赋值语句的左半部分 Z106 3. 因子表达式 Y107 :param token:108 :param expected: 期望值109 :return:110 """111 for t in var_table:112 if t.vname == token and t.vproc == proc and t.vkind == kind:113 if not expected:114 return False115 # err('CheckVarExist : expected=False, but now is True %s' % token)116 else:117 return True118 if expected:119 return False120 # err('CheckVarExist : expected=True, but now is False %s' % token)121 return False122def add_var(token, proc, kind, type, vlev):123 """124 只有两个地方会引入新变量:125 1. 变量定义和函数定义 V126 2. read B127 :param token:128 :param proc:129 :param kind: 分类vkind: 0..1(0—变量、1—形参)130 :param type:131 :param vlev:132 :return:133 """134 if is_var_exist(token, proc=proc, kind=kind, expected=False):135 err('In line %d AddVar : can not define a variable in twice' % line_no)136 var_table.append(Variable(token, proc, kind, type, vlev, len(var_table)))137 for i in range(0, proc.plev):138 if proc_table[i].plev < vlev or (proc_table[i].plev == vlev and proc_table[i].adr == proc.adr):139 proc_table[i].ladr += 1140def next_token(dyd_file):141 rep = None142 global line_no143 for line in dyd_file:144 debug(line)145 if line is not None and len(line) > 0:146 tmp = line.split()147 if tmp == table.EOF:148 return149 elif tmp is not None and tmp[0] == table.EOLN:150 line_no += 1151 continue152 elif len(tmp) == 2 and tmp[0]:153 while rep is not None and rep:154 rep = yield tmp[0], tmp[1]155 else:156 rep = yield tmp[0], tmp[1]157def match(token, token_id, keyword):158 if token is None:159 return False160 # 标识符161 if keyword == table.SYMBOL and token[0].isalpha() and token.isalnum():162 return True163 # 数字164 if keyword == table.CONST and token.isnumeric():165 return True166 # 关键词167 if keyword == token:168 return True169 # 关系运算符类170 if keyword is None and (token == table.EQUAL or token == table.NOT_EQUAL or token == table.LE or171 token == table.LITTLE or token == table.GE or token == table.GREATER):172 return True173 return False174def parse(dyd_file):175 S(next_token(dyd_file), 'main', 'void')176 for var in var_table:177 out_var(var.vname, var.vproc, var.vkind, var.vtype, var.vlen, var.vadr)178 # 计算每个proc的fadr和ladr,然后输出179 for proc in proc_table:180 for i in range(0, len(var_table) - 1):181 if var_table[i].vproc.adr == proc.adr:182 proc.fadr = i183 break184 for i in range(len(var_table) - 1, 0, -1):185 if var_table[i].vproc.adr == proc.adr:186 proc.ladr = i187 break188 out_proc(proc.pname, proc.ptype, proc.plev, proc.fadr, proc.ladr)189# 1. S->begin HE end190def S(token_generator, pname, ptype):191 global plevel, current_proc192 plevel += 1193 # 注意到函数有且仅有一个参数,而刚进入函数体时,变量表中的最后一个必为此参数194 if len(var_table) == 0:195 current_proc = Proc(pname, ptype, plevel)196 else:197 current_proc = Proc(pname, ptype, plevel)198 var_table[len(var_table) - 1].vproc = current_proc199 proc_table.append(current_proc)200 # 同时,由于在函数内可以直接把自身函数名当成一个变量来使用,所以需要把函数名加入到变量表201 add_var(pname, current_proc, 0, 'integer', plevel)202 token, token_id = next(token_generator)203 if not match(token, token_id, table.BEGIN):204 err('In line %d S : Not start with begin' % line_no)205 H(token_generator)206 # token, token_id = next(token_generator)207 # if not match(token, token_id, table.SEMICOLON):208 # err('S : A ; must follow H')209 E(token_generator)210 token, token_id = next(token_generator)211 if not match(token, token_id, table.END):212 err('In Line %d S : there must be an \'end\'' % line_no)213 plevel -= 1214 current_proc = proc_table[plevel - 1]215 return216# 2. H->integer V;H'217def H(token_generator):218 token, token_id = next(token_generator)219 if not match(token, token_id, table.INTEGER):220 err('In Line %d H : can not match integer' % line_no)221 V(token_generator)222 token, token_id = next(token_generator)223 if not match(token, token_id, table.SEMICOLON):224 err('In Line %d H : can not match ;' % line_no)225 _H(token_generator)226 return227# 3. H'->integer V;H'|e228def _H(token_generator):229 token, token_id = token_generator.send(True)230 # 没有匹配成功,可能是e,需要回退一步231 if not match(token, token_id, table.INTEGER):232 return233 # 匹配integer成功,需要把重复的这个yield冲刷掉234 next(token_generator)235 V(token_generator)236 token, token_id = next(token_generator)237 if not match(token, token_id, table.SEMICOLON):238 err('In Line %d H : can not match ;' % line_no)239 _H(token_generator)240# # 4. A->integer V241# def A(token_generator):242# token, token_id = next(token_generator)243# if not match(token, token_id, table.INTEGER):244# err('A : can not match integer')245# V(token_generator)246# 5. V->D|function D(M);S247def V(token_generator):248 token, token_id = token_generator.send(True)249 if not match(token, token_id, table.FUNCTION):250 D(token_generator)251 add_var(current_token, current_proc, 0, 'integer', plevel)252 return253 # 冲刷掉当前token254 next(token_generator)255 D(token_generator)256 func_name = current_token257 token, token_id = next(token_generator)258 if not match(token, token_id, table.LEFT_BRACKET):259 err('In line %d V : can not match (' % line_no)260 M(token_generator)261 # 由于current_proc尚未生成,先赋值为当前proc,在进入函数时需要重新设置262 add_var(current_token, current_proc, 1, 'integer', plevel + 1)263 token, token_id = next(token_generator)264 if not match(token, token_id, table.RIGHT_BRACKET):265 err('In Line %d V : can not match )' % line_no)266 token, token_id = next(token_generator)267 if not match(token, token_id, table.SEMICOLON):268 err('In Line %d V : can not match ;' % line_no)269 S(token_generator, func_name, 'integer')270# 6. D->GD'271def D(token_generator):272 if not G(token_generator):273 err('In Line %d D : match %s error' % (line_no, current_token))274 _D(token_generator)275 return276# 7. D'->GD'|ND'|e277def _D(token_generator):278 if G(token_generator):279 _D(token_generator)280 elif N(token_generator):281 _D(token_generator)282 else:283 return284# 8. G->a|b|c....285def G(token_generator):286 token, token_id = token_generator.send(True)287 if match(token, token_id, table.SYMBOL):288 next(token_generator)289 global current_token290 current_token = token291 return True292 return False293# 9. N->0|1|2...294def N(token_generator):295 token, token_id = token_generator.send(True)296 if match(token, token_id, table.CONST):297 next(token_generator)298 global current_const299 current_const = token300 return True301 return False302# 10. M->D303def M(token_generator):304 D(token_generator)305# 11. E->BE'306def E(token_generator):307 B(token_generator)308 _E(token_generator)309 return310# 12. E'->;BE'|e311def _E(token_generator):312 token, token_id = token_generator.send(True)313 if not match(token, token_id, table.SEMICOLON):314 return315 next(token_generator)316 B(token_generator)317 _E(token_generator)318# 13. B->read(D)|write(D)|if U then B else B|Z319def B(token_generator):320 token, token_id = token_generator.send(True)321 # func_is_read = match(token, token_id, table.READ)322 if match(token, token_id, table.READ) or match(token, token_id, table.WRITE):323 # 成功,冲刷324 next(token_generator)325 token, token_id = next(token_generator)326 if not match(token, token_id, table.LEFT_BRACKET):327 err('In Line %d B : can not match (' % line_no)328 D(token_generator)329 if not is_var_exist(current_token, current_proc, 0, True):330 err('In Line %d B : can not find token %s' % (line_no, current_token))331 # if func_is_read:332 # add_var(current_token, current_proc, 0, 'integer', plevel)333 token, token_id = next(token_generator)334 if not match(token, token_id, table.RIGHT_BRACKET):335 err('In Line %d B : can not match )' % line_no)336 elif match(token, token_id, table.IF):337 # 成功,冲刷338 next(token_generator)339 U(token_generator)340 token, token_id = next(token_generator)341 if not match(token, token_id, table.THEN):342 err('In Line %d B : can not match then' % line_no)343 B(token_generator)344 token, token_id = next(token_generator)345 if not match(token, token_id, table.ELSE):346 err('In Line %d B : can not match else' % line_no)347 B(token_generator)348 else:349 Z(token_generator)350# 14. Z->D:=K351def Z(token_generator):352 D(token_generator)353 if not is_var_exist(current_token, current_proc, 0, True):354 err('In Line %d Z : token %s not defined' % (line_no, current_token))355 token, token_id = next(token_generator)356 if not match(token, token_id, table.ASSIGN):357 err('In Line %d Z : can not match := %s' % (line_no, token))358 K(token_generator)359# 15. K->LK'360def K(token_generator):361 L(token_generator)362 _K(token_generator)363# 16. K'=-LK'|e364def _K(token_generator):365 token, token_id = token_generator.send(True)366 if not match(token, token_id, table.SUB):367 return368 # 冲刷369 next(token_generator)370 L(token_generator)371 _K(token_generator)372# 17. L->YL'373def L(token_generator):374 Y(token_generator)375 _L(token_generator)376# 18. L'->*YL'|e377def _L(token_generator):378 token, token_id = token_generator.send(True)379 if not match(token, token_id, table.MUL):380 return381 # 冲刷382 next(token_generator)383 Y(token_generator)384 _L(token_generator)385# 19. Y->NQ'|GD'|D(M)386# 其中,D == GD'387def Y(token_generator):388 # 先检查是否是数字389 if N(token_generator):390 _Q(token_generator)391 return392 # 然后检查是否是函数调用393 D(token_generator)394 func_name = current_token395 token, token_id = token_generator.send(True)396 if not match(token, token_id, table.LEFT_BRACKET):397 # 不是函数调用398 if not is_var_exist(current_token, current_proc, 0, True):399 err('In Line %d Y : %s is not defined' % (line_no, current_token))400 _D(token_generator)401 return402 # 确实是函数403 # 检查函数是否已定义404 flag = False405 for proc in proc_table:406 if proc.pname == func_name:407 flag = True408 break409 if not flag:410 err('In Line %d P : function not defined' % line_no)411 # 冲刷412 next(token_generator)413 K(token_generator)414 token, token_id = next(token_generator)415 if not match(token, token_id, table.RIGHT_BRACKET):416 err('In Line %d P : can not match )' % line_no)417# 20. Q->NQ'418def Q(token_generator):419 if not N(token_generator):420 err('In Line %d Q : match number error %s' % (line_no, current_token))421 _Q(token_generator)422# 21. Q'->NQ'|e423def _Q(token_generator):424 if N(token_generator):425 _Q(token_generator)426 else:427 return428# 23. U->KOK429def U(token_generator):430 K(token_generator)431 O(token_generator)432 K(token_generator)433# 24. O-><|<=|=...434def O(token_generator):435 token, token_id = next(token_generator)436 if not match(token, token_id, None):...

Full Screen

Full Screen

test_utils.py

Source:test_utils.py Github

copy

Full Screen

1# -*- coding: utf-8 -*-2from django.test import TestCase, tag3from django.utils import six4from django.utils.crypto import salted_hmac5from django.utils.http import int_to_base366import factories7from workflow.models import Dashboard8from .. import utils9@tag('pkg')10class TokenGeneratorTest(TestCase):11 def setUp(self):12 self.token_generator = utils.TokenGenerator()13 def test_get_attr_by_suffix_exist(self):14 tola_user = factories.TolaUser()15 attr = self.token_generator._get_attr_by_suffix(tola_user, 'name')16 self.assertEqual(attr, tola_user.name)17 def test_get_attr_by_suffix_not_exist(self):18 tola_user = factories.TolaUser()19 attr = self.token_generator._get_attr_by_suffix(tola_user, 'test')20 self.assertIsNone(attr)21 def test_make_hash_value_with_uuid_and_no_flag(self):22 tola_user = factories.TolaUser()23 timestamp = self.token_generator._num_days(24 self.token_generator._today())25 expected_hash = (26 six.text_type(tola_user.pk) + tola_user.tola_user_uuid.__str__()27 + six.text_type(timestamp)28 )29 generated_hash = self.token_generator._make_hash_value(30 tola_user, timestamp)31 self.assertEqual(generated_hash, expected_hash)32 def test_make_hash_value_with_uuid_and_flag(self):33 tola_user = factories.TolaUser()34 timestamp = self.token_generator._num_days(35 self.token_generator._today())36 expected_hash = (37 six.text_type(True) + tola_user.tola_user_uuid.__str__()38 + six.text_type(timestamp)39 )40 generated_hash = self.token_generator._make_hash_value(41 tola_user, timestamp, flag=True)42 self.assertEqual(generated_hash, expected_hash)43 def test_make_token_with_timestamp(self):44 tola_user = factories.TolaUser()45 timestamp = self.token_generator._num_days(46 self.token_generator._today())47 test_hash = (48 six.text_type(True) + tola_user.tola_user_uuid.__str__()49 + six.text_type(timestamp)50 )51 ts_b36 = int_to_base36(timestamp)52 hash = salted_hmac(self.token_generator.key_salt,53 test_hash).hexdigest()[::2]54 generated_hash = self.token_generator._make_token_with_timestamp(55 tola_user, timestamp, flag=True)56 self.assertEqual(generated_hash, '{}-{}'.format(ts_b36, hash))57 def test_check_token_no_public_attribute(self):58 tola_user = factories.TolaUser()59 with self.assertRaises(AttributeError) as context:60 self.token_generator.check_token(tola_user, 'TokenTest')61 self.assertTrue('\'dict\' object has no attribute \'test\''62 in context.exception)63 def test_check_token_token_is_none(self):64 tola_user = factories.TolaUser()65 is_valid = self.token_generator.check_token(tola_user, None)66 self.assertFalse(is_valid)67 def test_check_token_instance_is_none(self):68 is_valid = self.token_generator.check_token(None, 'TokenTest')69 self.assertFalse(is_valid)70 def test_check_token_token_wrong_format(self):71 dashboard = factories.Dashboard\72 (public={'all': False, 'org': False, 'url': True})73 timestamp = self.token_generator._num_days(74 self.token_generator._today())75 test_hash = (76 six.text_type(dashboard.public) +77 dashboard.dashboard_uuid.__str__() +78 six.text_type(timestamp)79 )80 ts_b36 = int_to_base36(timestamp)81 hash = salted_hmac(self.token_generator.key_salt,82 test_hash).hexdigest()[::2]83 final_hash = '{}{}'.format(ts_b36, hash)84 is_valid = self.token_generator.check_token(dashboard, final_hash,85 dashboard.public)86 self.assertFalse(is_valid)87 def test_check_token_invalid_timestamp_token(self):88 dashboard = factories.Dashboard(89 public={'all': False, 'org': False, 'url': True})90 timestamp = self.token_generator._num_days(91 self.token_generator._today())92 test_hash = (93 six.text_type(dashboard.public) +94 dashboard.dashboard_uuid.__str__() +95 six.text_type(timestamp)96 )97 hash = salted_hmac(self.token_generator.key_salt,98 test_hash).hexdigest()[::2]99 final_hash = '{}-{}'.format(timestamp, hash)100 is_valid = self.token_generator.check_token(dashboard, final_hash,101 dashboard.public)102 self.assertFalse(is_valid)103 def test_check_token_no_public(self):104 dashboard = factories.Dashboard()105 timestamp = self.token_generator._num_days(106 self.token_generator._today())107 test_hash = (108 six.text_type(dashboard.pk) +109 dashboard.dashboard_uuid.__str__() +110 six.text_type(timestamp)111 )112 hash = salted_hmac(self.token_generator.key_salt,113 test_hash).hexdigest()[::2]114 final_hash = '{}-{}'.format(timestamp, hash)115 is_valid = self.token_generator.check_token(dashboard, final_hash)116 self.assertFalse(is_valid)117 def test_check_token_invalid_token(self):118 dashboard = factories.Dashboard(119 public={'all': False, 'org': False, 'url': True})120 timestamp = self.token_generator._num_days(121 self.token_generator._today())122 test_hash = (123 six.text_type(True) + dashboard.dashboard_uuid.__str__() +124 six.text_type(timestamp)125 )126 hash = salted_hmac(self.token_generator.key_salt,127 test_hash).hexdigest()[::2]128 final_hash = '{}-{}'.format(timestamp, hash)129 is_valid = self.token_generator.check_token(dashboard, final_hash)130 self.assertFalse(is_valid)131 def test_check_token_success_with_flag(self):132 dashboard = factories.Dashboard(133 public={'all': False, 'org': False, 'url': True})134 timestamp = self.token_generator._num_days(135 self.token_generator._today())136 test_hash = (137 six.text_type(dashboard.public['url']) +138 dashboard.dashboard_uuid.__str__() +139 six.text_type(timestamp)140 )141 ts_b36 = int_to_base36(timestamp)142 hash = salted_hmac(self.token_generator.key_salt,143 test_hash).hexdigest()[::2]144 final_hash = '{}-{}'.format(ts_b36, hash)145 is_valid = self.token_generator.check_token(146 dashboard, final_hash, dashboard.public['url'])147 self.assertTrue(is_valid)148 def test_check_token_success_without_flag(self):149 dashboard = factories.Dashboard(150 public={'all': False, 'org': False, 'url': True})151 timestamp = self.token_generator._num_days(152 self.token_generator._today())153 test_hash = (154 six.text_type(dashboard.pk) +155 dashboard.dashboard_uuid.__str__() +156 six.text_type(timestamp)157 )158 ts_b36 = int_to_base36(timestamp)159 hash = salted_hmac(self.token_generator.key_salt,160 test_hash).hexdigest()[::2]161 final_hash = '{}-{}'.format(ts_b36, hash)162 is_valid = self.token_generator.check_token(dashboard, final_hash)...

Full Screen

Full Screen

test_tokens.py

Source:test_tokens.py Github

copy

Full Screen

1from unittest.mock import Mock, patch2from django.test import SimpleTestCase3from django.utils.crypto import salted_hmac4from django.utils.http import int_to_base365from projects.tokens import token_generator6class ApiTokenGeneratorTest(SimpleTestCase):7 """ """8 def setUp(self):9 self.project = Mock(pk=1, group_id=1, author_id=2)10 self.project2 = Mock(pk=2, group_id=1, author_id=2)11 def test_make_token(self):12 token = token_generator.make_token(self.project)13 id_b36 = int_to_base36(self.project.pk)14 expected = salted_hmac(15 token_generator.key_salt,16 token_generator._make_hash_value(self.project),17 secret=token_generator.secret,18 ).hexdigest()19 self.assertEqual(token, '-'.join([id_b36, expected]))20 @patch.object(token_generator, 'get_project')21 def test_check_token(self, mget_project):22 mget_project.return_value = self.project23 token = token_generator.make_token(self.project)24 token2 = token_generator.make_token(self.project2)25 self.assertTrue(token_generator.check_token(token))26 self.assertFalse(token_generator.check_token(token2))27 def test_check_token_with_empty_args(self):28 self.assertFalse(token_generator.check_token(None))29 def test_make_hash_value(self):30 hashv = token_generator._make_hash_value(self.project)31 self.assertEqual(hashv, "121")32 @patch.object(token_generator, 'get_project_id', return_value=None)33 def test_get_object_invalid_valid(self, mproject_id):34 self.assertIsNone(token_generator.get_project('invalid'))35 mproject_id.assert_called_with('invalid')36 @patch('projects.tokens.apps.get_model', return_value=Mock())37 @patch.object(token_generator, 'get_project_id', return_value=1)38 def test_get_object_valid_token(self, mproject_id, model):39 self.assertIsNotNone(token_generator.get_project('valid'))40 model().objects.filter.assert_called_with(pk=1)41 model().objects.filter().first.assert_called_with()42 def test_get_object_id_invalid_token(self):43 self.assertIsNone(token_generator.get_project_id('invalid'))44 def test_get_object_id_valid_token(self):...

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 localstack 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