Best Python code snippet using autotest_python
DTW.py
Source:DTW.py
1import json2import numpy as np3from dtw import *4import matplotlib5matplotlib.use('tkAgg')6import matplotlib.pyplot as plt7import pandas as pd8sys.path.append("../")9from data_dict import data_dict10def get_data(filename):11 df = pd.read_csv(filename)12 df['time'] = pd.to_datetime(df['time'], format='%Y-%m-%d %H:%M:%S.%f')13 return df['time'].to_numpy(), df['value'].to_numpy()14def get_hits(x_signal, signal, x_template, template):15 len_signal = signal.shape[0]16 len_template = template.shape[0]17 x = []18 dist = []19 for i in range(0, len_signal-len_template, int(len(template)/3)):20 print(i / (len_signal - len_template))21 al = dtw(signal[i:i+len_template], template)22 di = al.distance23 xi = x_signal[i+len_template]24 dist.append(di)25 x.append(xi)26 return np.array(x), np.array(dist)27def get_similarity(signal, template):28 if len(template) > len(signal):29 return float('inf')30 al = dtw(signal[-len(template):], template)31 return al.normalizedDistance32def default_filter_func(a):33 return a.to_numpy()34def fft_filter_func(a):35 T = 1.0 / 50.036 N = len(a)37 f = np.linspace(0, 1.0/(2.0*T), int(N/2))38 res = np.fft.rfft(a - np.mean(a))39 my_filter = np.bitwise_or(f < 0.1, f > 25)40 power_filter = np.abs(res[:int(N/2)]) < 341 ind = np.where(my_filter)42 res[ind] = 043 ind2 = np.where(power_filter)44 res[ind2] = 045 ires = np.fft.irfft(res)46 return ires47def analysis(x_wc, wc, x_tap, tap, filter_func=default_filter_func):48 print("Performing DTW analysis")49 wc = filter_func(wc)50 x_wc = x_wc[:len(wc)]51 tap = filter_func(tap)52 x_tap = x_tap[:len(tap)]53 for entry in data_dict:54 if len(entry['wc']) == 0 and len(entry['tap water']) == 0:55 continue56 x_signal, signal = get_data('../data/dataFull/' + entry['filename'])57 signal = filter_func(signal)58 x_signal = x_signal[:len(signal)]59 x1, dist_wc = get_hits(x_signal, signal, x_wc, wc)60 x2, dist_tap = get_hits(x_signal, signal, x_tap, tap)61 fig, axs = plt.subplots(3)62 axs[0].plot(x_signal, signal, color='b')63 for wc_entry in entry['wc']:64 x_wc_entry, y_wc_entry = x_signal[wc_entry["start"]*50:wc_entry["end"]*50], signal[wc_entry["start"]*50:wc_entry["end"]*50]65 axs[0].plot(x_wc_entry, y_wc_entry, color='r', label='wc entry')66 for tap_entry in entry['tap water']:67 x_tap_entry, y_tap_entry = x_signal[tap_entry["start"]*50:tap_entry["end"]*50], signal[tap_entry["start"]*50:tap_entry["end"]*50]68 axs[0].plot(x_tap_entry, y_tap_entry, color='g', label='tap water entry')69 dist_wc = dist_wc / len(wc)70 dist_tap = dist_tap / len(tap)71 my_max = max(max(dist_wc), max(dist_tap))72 axs[1].plot(x1, dist_wc, color='r', label='normalized dist to wc')73 axs[1].plot(x2, dist_tap, color='g', label='normalized dist to tap water')74 axs[1].set_ylim(0, my_max)75 #fig.legend()76 ind = np.where(dist_tap < 0.017)77 is_tap_signal = np.zeros(len(dist_tap))78 is_tap_signal[ind] = 179 axs[2].plot(x2, is_tap_signal)80 fig.savefig(entry['filename'] + ".png")81def fft_analysis(x_signal, signal):82 print("Performing FFT analysis")83 T = 1.0 / 50.084 N = len(signal)85 f = np.linspace(0, 1.0/(2.0*T), int(N/2))86 res = np.fft.rfft(signal - np.mean(signal))87 fig_noisy, axs_noisy = plt.subplots(2)88 axs_noisy[0].plot(x_signal, signal)89 axs_noisy[1].plot(f, 2.0 / N * np.abs(res[:int(N/2)]))90 my_filter = np.bitwise_or(f < 0.1, f > 15)91 power_filter = np.abs(res[:int(N/2)]) < 1092 ind = np.where(my_filter)93 res[ind] = 094 ind2 = np.where(power_filter)95 res[ind2] = 096 ires = np.fft.irfft(res)97 fig_filt, axs_filt = plt.subplots(2)98 axs_filt[0].plot(x_signal, ires)99 axs_filt[1].plot(f, 2.0 / N * np.abs(res[:int(N/2)]))100 plt.legend()101 plt.show()102def old_dtw():103 x_source_wc, source_wc = get_data('data2.csv')104 wc_start, wc_end = 492, 573105 x_wc, wc = x_source_wc.iloc[wc_start*50:wc_end*50], source_wc.iloc[wc_start*50:wc_end*50]106 x_source_tap, source_tap = get_data('data3.csv')107 tap_start, tap_end = 216, 236108 x_tap, tap = x_source_tap.iloc[tap_start*50:tap_end*50], source_tap.iloc[tap_start*50:tap_end*50]109 analysis(x_wc, wc, x_tap, tap)110def show_dtw():111 sub_len = 20112 sub_signal = np.zeros(sub_len)113 for i in range(sub_len):114 sub_signal[i] = 1/10 * 2.73**(-(i-(sub_len/2))**2 / 10)115 x_source_tap, source_tap = get_data('data3.csv')116 my_len = 100117 template_start, template_end = 216, (216 + my_len)118 tap_start, tap_end = 500, (500+my_len)119 template = source_tap[template_start:template_end]120 tap = source_tap[tap_start:tap_end]121 template[10:10+sub_len] = template[10:10+sub_len] + sub_signal122 template[40:40+sub_len] = template[40:40+sub_len] + sub_signal123 tap[30:30+sub_len] = tap[30:30+sub_len] + sub_signal124 tap[60:60+sub_len] = tap[60:60+sub_len] + sub_signal125 alignment = dtw(tap, template, keep_internals=True)126 #alignment.plot(type="twoway", offset=-1)127 alignment.plot(type="twoway", offset=-1, xlab="Sample index", ylab=r"magnetic intensity ($\mu$T)")128 print(np.linalg.norm(tap-template))129 print(alignment.normalizedDistance)130 #plt.plot(x_source_tap, source_tap, color='b')131 #plt.plot(x_source_tap[template_start:template_end], source_tap[template_start:template_end], color='r')132 #plt.plot(x_source_tap[tap_start:tap_end], source_tap[tap_start:tap_end], color='r')133 #plt.show()134 #x_tap, tap = x_source_tap.iloc[tap_start*50:tap_end*50], source_tap.iloc[tap_start*50:tap_end*50]135def get_templates():136 folder = '../data/dataFull/'137 data_file_list = ['1625807700000000000-1625808600000000000.csv', '1625631240-1625632140.csv', '1625770800000000000-1625771700000000000.csv']138 taps, wcs = [], []139 for data_file in data_file_list:140 _, source_data = get_data(folder + data_file)141 for dd in data_dict:142 if dd['filename'] == data_file:143 for tap_water in dd['tap water']:144 taps.append(source_data[int(tap_water['start']*50):int(tap_water['end']*50)])145 for wc in dd['wc']:146 wcs.append(source_data[int(wc['start']*50):int(wc['end']*50)])147 res = []148 for tap in taps:149 res.append({150 "class": "tap water",151 "template": tap,152 })153 for wc in wcs:154 res.append({155 "class": "wc",156 "template": wc,157 })158 return res159def create_similarity_measures(templates):160 similarities = []161 i = 0162 for data in data_dict:163 print(str(i) + " / " + str(len(data_dict)))164 i += 1165 filepath = "../data/dataFull/" + data["filename"]166 _, signal = get_data(filepath)167 for entry_class in ["wc", "tap water"]:168 for entry in data[entry_class]:169 min_dists = {"wc": float('inf'), "tap water": float('inf')}170 for template in templates:171 dist = get_similarity(signal[:int(entry["end"]*50)], template["template"])172 if template["class"] == "wc" and dist < min_dists["wc"]:173 min_dists["wc"] = dist174 elif template["class"] == "tap water" and dist < min_dists["tap water"]:175 min_dists["tap water"] = dist176 similarities.append({177 "filepath": filepath,178 "min_dists": min_dists,179 "class": entry_class,180 })181 with open("simil.txt", "w+") as f:182 for sim in similarities:183 f.write(str(sim) + "\n")184def parse_similarity_measures(filepath="simil.txt"):185 similarities = []186 with open(filepath, "r") as f:187 for line in f.read().splitlines():188 s = json.loads(line)189 similarities.append(s)190 return similarities191min_diff = 1000192max_diff = -1000193def predict(similarity, thresh = 0):194 global min_diff195 global max_diff196 diff = similarity["min_dists"]["wc"] - similarity["min_dists"]["tap water"]197 if diff < min_diff:198 min_diff = diff199 if diff > max_diff and diff < 10:200 max_diff = diff201 if diff > thresh:202 return "wc"203 else:204 return "tap water"205def test_similarity_measures(similarities, thresh=0):206 wc_ok, wc_nok, tap_ok, tap_nok = 0, 0, 0, 0207 for simil in similarities:208 prediction = predict(simil, thresh)209 if prediction == "wc" and simil["class"] == "wc":210 wc_ok += 1211 elif prediction == "tap water" and simil["class"] == "wc":212 wc_nok += 1213 elif prediction == "tap water" and simil["class"] == "tap water":214 tap_ok += 1215 elif prediction == "wc" and simil["class"] == "tap water":216 tap_nok += 1217 else:218 print("ERRROR")219 res = {220 "wc_ok": wc_ok,221 "wc_nok": wc_nok,222 "tap_ok": tap_ok,223 "tap_nok": tap_nok,224 "accuracy": (wc_ok + tap_ok) / (wc_ok + tap_ok + wc_nok + tap_nok),225 }226 return res227def test_templates(templates):228 wc_ok, wc_nok, tap_ok, tap_nok = 0, 0, 0, 0229 i = 0230 for data in data_dict:231 print(str(i) + " / " + str(len(data_dict)))232 i += 1233 _, signal = get_data("../data/dataFull/" + data["filename"])234 for entry_class in ["wc", "tap water"]:235 for entry in data[entry_class]:236 min_dist = float('inf')237 best_class = ""238 for template in templates:239 dist = get_similarity(signal[:int(entry["end"]*50)], template["template"])240 if dist < min_dist:241 min_dist = dist242 best_class = template["class"]243 if entry_class == "wc" and entry_class == best_class:244 wc_ok += 1245 elif entry_class == "wc" and entry_class != best_class:246 wc_nok += 1247 elif entry_class == "tap water" and entry_class == best_class:248 tap_ok += 1249 else:250 tap_nok += 1251 print("wc correct: " + str(wc_ok) + " / (" + str(wc_ok) + " + " + str(wc_nok) + ") = " + str(wc_ok / (wc_ok + wc_nok)))252 print("tap correct: " + str(tap_ok) + " / (" + str(tap_ok) + " + " + str(tap_nok) + ") = " + str(tap_ok / (tap_ok + tap_nok)))253 return (wc_ok + tap_ok) / (wc_ok + tap_ok + wc_nok + tap_nok)254def dtw_classifier(similarities):255 best = None256 best_thresh = 0257 for thresh in np.linspace(-0.00863405061896113*10,0.010766850570994357*10, 10):258 acc = test_similarity_measures(similarities, thresh = thresh)259 if best is None or acc["accuracy"] > best["accuracy"]:260 best = acc261 best_thresh = thresh262 print(best)263 print("Best thresh: " + str(thresh))264def clean_simil():265 with open("simil.txt", "rt") as file:266 data = file.read()267 data = data.replace("'", "\"")268 data = data.replace("inf", str(10000))269 with open("simil.txt", "wt") as file:270 file.write(data)271if __name__ == '__main__':272 print("Performing DTW test")273 #show_dtw()274 generate_similarities = False275 if generate_similarities:276 templates = get_templates()277 create_similarity_measures(templates)278 clean_simil()279 else:280 similarities = parse_similarity_measures()...
k-NN.py
Source:k-NN.py
1import matplotlib2import numpy as np3import sys4sys.path.append("../recording")5sys.path.append("../")6from SineFit import guess_fft, sin_fit7from math import sqrt8matplotlib.use('tkAgg')9import matplotlib.pyplot as plt10import pandas as pd11from scipy import optimize as opt12from sklearn.neighbors import KNeighborsClassifier13from sklearn.model_selection import train_test_split14from dtw import *15from data_dict import data_dict16second_size = 5017def get_data(filename):18 df = pd.read_csv(filename)19 #for i in range(0, df['time'].size):20 # df.loc[i, 'time'] = pd.to_datetime(df.loc[i, 'time'], format='%Y-%m-%d %H:%M:%S.%f').timestamp()21 df['time'] = pd.to_datetime(df['time'], format='%Y-%m-%d %H:%M:%S.%f').values.astype(float)22 return df['time'], df['value']23def fft_filter_func(a):24 T = 1.0 / 50.025 N = len(a)26 f = np.linspace(0, 1.0/(2.0*T), int(N/2))27 res = np.fft.rfft(a - np.mean(a))28 my_filter = np.bitwise_or(f < 0.1, f > 25)29 power_filter = np.abs(res[:int(N/2)]) < 330 ind = np.where(my_filter)31 res[ind] = 032 ind2 = np.where(power_filter)33 res[ind2] = 034 ires = np.fft.irfft(res)35 return ires36def fit_sine_curve_freq(x, y, guess_f=guess_fft):37 """38 1st method to get period from data39 :param data: path of file to read data from40 :param guess_f: function to estimate the points41 :return:42 """43 x = np.array(x.astype(float).values)44 y = np.array(y.astype(float).values)45 x0 = x[0]46 for i in range(0, x.size):47 x[i] -= x048 guess = guess_f(x, y)49 try:50 params, params_covariance = opt.curve_fit(f=sin_fit, xdata=x, ydata=y, p0=guess)51 amplitude = params[0]52 freq = params[1]53 phase = params[2]54 offset = params[3]55 return freq56 except:57 return -158def fit_sine_curve_knn(x, y, freqs=[1, 10, 15, 25]):59 n_features = len(freqs) - 160 res = np.zeros(n_features)61 for i in range(0,len(x) - second_size, second_size):62 f = fit_sine_curve_freq(x[i:i+second_size], y[i:i+second_size]) * 1e963 if f > 0:64 for i in range(n_features):65 if f > freqs[i] and f < freqs[i+1]:66 res[i] = res[i] + 167 res = res / (len(x) / second_size)68 return res69"""70Return a list of N tuples corresponding to (frequency - amplitude) for71frequencies between 1 and 25Hz72x is considered to be at 50Hz73"""74def fft_knn(x, y, freqs=[1, 10, 15, 25]):75 T = 1.0 / 50.076 N = len(y)77 f = np.linspace(0, 1.0/(2.0*T), int(N/2))78 res_fft = np.fft.rfft(y - np.mean(y))79 highpass_filter = f < 0.980 ind = np.where(highpass_filter)81 res_fft[ind] = 082 n_features = len(freqs) - 183 res = np.zeros(n_features)84 for idx in range(n_features):85 filt = np.bitwise_and(f > freqs[i], f < freqs[i+1])86 ind = np.where(filt)87 filtered_values = res_fft[ind]88 res[idx] = np.mean(filtered_values)89 return res90def knn_view(knn_func=fft_knn, freqs=[0, 8.33, 16.66, 25]):91 fig = plt.figure()92 ax = fig.add_subplot(projection='3d')93 for entry in data_dict:94 if len(entry["wc"]) == 0 and len(entry["tap water"]) == 0:95 continue96 x_signal, signal = get_data('../data/' + entry['filename'])97 for wc_entry in entry["wc"]:98 x_wc, wc = x_signal[int(wc_entry["start"]*50):int(wc_entry["end"]*50)], signal[int(wc_entry["start"]*50):int(wc_entry["end"]*50)]99 xyz = knn_func(x_wc, wc, freqs=freqs)100 ax.scatter([xyz[0]], [xyz[1]], [xyz[2]], marker='o', color='r')101 for tap_entry in entry["tap water"]:102 x_tap, tap = x_signal[int(tap_entry["start"]*50):int(tap_entry["end"]*50)], signal[int(tap_entry["start"]*50):int(tap_entry["end"]*50)]103 xyz = knn_func(x_tap, tap, freqs=freqs)104 ax.scatter([xyz[0]], [xyz[1]], [xyz[2]], marker='^', color='g')105 ax.set_xlabel('f1 mean amplitude')106 ax.set_ylabel('f2 mean amplitude')107 ax.set_zlabel('f3 mean amplitude')108 plt.show()109def read_data_dict(folderPath, knn_func, freqs, data_dict):110 x, y = [], []111 for data in data_dict:112 entry = data["data"]113 clas = data["class"]114 x_signal, signal = get_data(folderPath + data['filename'])115 tmp_x, tmp_y = x_signal[int(entry["start"]*50):int(entry["end"]*50)], signal[int(entry["start"]*50):int(entry["end"]*50)]116 xyz = knn_func(tmp_x, tmp_y, freqs)117 x.append(xyz)118 y.append(clas)119 return x, y120def parse_dict(data_dict):121 entries = []122 for entry in data_dict:123 for wc_entry in entry["wc"]:124 entries.append({"data": wc_entry,"class": "wc","filename":entry["filename"]})125 for tap_entry in entry["tap water"]:126 entries.append({"data": tap_entry,"class": "tap","filename":entry["filename"]})127 return entries128def knn_getdata(knn_func=fft_knn, freqs=[0,8.33, 16.66, 25], test_size=0.5):129 entries = parse_dict(data_dict)130 dict_train, dict_test = train_test_split(entries, test_size=test_size, random_state=2)131 X_train, y_train = read_data_dict('../data/dataFull/', knn_func, freqs, dict_train)132 X_test, y_test = read_data_dict('../data/dataFull/', knn_func, freqs, dict_test)133 return X_train, y_train, X_test, y_test134def evaluate_knn(neigh, X_test, y_test):135 wc_ok, wc_nok, tap_ok, tap_nok = 0, 0, 0, 0136 for X,y in zip(X_test, y_test):137 pred = neigh.predict([X])138 if (str(pred[0]) == str(y)):139 if y == 'wc':140 wc_ok = wc_ok + 1141 elif y == 'tap':142 tap_ok = tap_ok + 1143 else:144 if y == 'wc':145 wc_nok = wc_nok + 1146 elif y == 'tap':147 tap_nok = tap_nok + 1148 print("wc correct: " + str(wc_ok) + " / (" + str(wc_ok) + " + " + str(wc_nok) + ") = " + str(wc_ok / (wc_ok + wc_nok)))149 print("tap correct: " + str(tap_ok) + " / (" + str(tap_ok) + " + " + str(tap_nok) + ") = " + str(tap_ok / (tap_ok + tap_nok)))150 return (wc_ok + tap_ok) / (wc_ok + tap_ok + wc_nok + tap_nok)151def full_knn(pre_process=fit_sine_curve_knn, metric=None, freqs=[0,8.33,16.66,25], test_size=0.5, K=5):152 X_train, y_train, X_test, y_test = knn_getdata(pre_process, freqs=freqs, test_size=test_size)153 if metric is None:154 metric = 'minkowski'155 neigh = KNeighborsClassifier(n_neighbors=K, metric=metric)156 neigh.fit(X_train, y_train)157 return evaluate_knn(neigh, X_test, y_test)158def my_euclidean(X, Y):159 total = 0160 for x,y in zip(X, Y):161 total += (x-y)**2162 return sqrt(total)163def my_dtw(X, Y):164 al = dtw(X, Y)165 return al.distance166def tune_parameters():167 n_dim = [20,25,50]168 K = [1,3,5]169 metrics = [my_euclidean, my_dtw]170 max_success_rate = 0171 best_K = 0172 best_dim = 0173 best_metric = "euclidean"174 for dim in n_dim:175 for k in K:176 for metric in metrics:177 success_rate = full_knn(metric=metric, freqs=np.linspace(0, 25, dim), test_size=0.3, K=k)178 if success_rate > max_success_rate:179 max_success_rate = success_rate180 best_K = k181 best_dim = dim182 if metric == my_euclidean:183 best_metric = "euclidean"184 else:185 best_metric = "dtw"186 retval = {187 "K": best_K,188 "dim": dim,189 "success_rate": max_success_rate,190 "metric": best_metric,191 }192 return retval193if __name__ == '__main__':194 params = tune_parameters()...
tap_processor.py
Source:tap_processor.py
1# -*- coding: utf-8 -*-2import re3TAP_NG = 04TAP_OK = 15TAP_SKIP = 26TAP_TODO = 37class TAP_Processor(object):8 #===============================================================================9 # |-----result------|10 # _resultListæ ¼å¼ï¼ï¼»ï¼»msgTypeï¼messageï¼½ï¼ï¼»msgType ,messageï¼½.......ï¼½11 # ^ ^ 12 # TAP_NG TAP_OK 13 #=============================================================================== 14 def __init__(self):15 self._resultList = []16 17 def clear(self):18 self._resultList = []19 20 #addæä½ï¼ by list21 def addResultList(self , result_List): 22 self._resultList.extend(result_List)23 24 #addæä½ï¼ by simple result 25 def addResult(self ,msgType , message):26 self._resultList.append([msgType, message])27 28 #loadæä½ï¼ by tap file29 def loadTap(self , tapFile):30 with open(tapFile , 'rb') as f:31 for line in f:32 if re.match(r'\S+', line):33 if re.match(r'[^\d+..\d+]',line):34 self._resultList.append(self.tapLine2result(line))35 #dumpæä½ to file36 def dump2file(self, outPathName): 37 result_list = self.dump2strList()38 39 with open(outPathName , 'wb') as f:40 f.writelines(result_list)41 42 #dumpæä½ to string list 43 def dump2strList(self):44 result_list = ['1..%d\n'%len(self._resultList)]45 46 for i in range(0, len(self._resultList)):47 result_list.append(self.result2tapLine(self._resultList[i], i+1)+'\n')48 49 return result_list50 51 #è·åææresult52 def getAllResult(self):53 result_list = self._resultList54 55 return result_list56 57 #è·åææresult,转æåå
¸ç±»å58 def getAllResultDict(self):59 result_list = self._resultList60 result_dict = {}61 result_map = ["NG","OK","Not executed","NG"]62 for item in result_list:63 result_dict[item[1]] = result_map[item[0]]64 65 return result_dict66 67 #searchæä½ all successï½fail|skip|TODO result68 def searchByType(self, resultType):69 result_list = []70 71 for result in self._resultList:72 if result[0] == resultType:73 result_list.append(result)74 75 return result_list76 77 #searchæä½ message match one REGEX78 def searchByMessage(self , REGEX):79 result_list = []80 81 for result in self._resultList:82 if re.search(REGEX, result[1]):83 result_list.append(result)84 85 return result_list 86 #result to tapLine87 def result2tapLine(self, result , i):88 tapPrintLine = ''89 90 if result[0] == TAP_NG:91 tapPrintLine = "not ok %d - %s"%(i,result[1])92 elif result[0] == TAP_OK:93 tapPrintLine = "ok %d - %s"%(i,result[1])94 elif result[0] == TAP_SKIP:95 tapPrintLine = "not ok %d - %s # SKIP skip this test"%(i,result[1])96 elif result[0] == TAP_TODO:97 tapPrintLine = "not ok %d - %s # TODO need redo, source list error"%(i,result[1])98 else:99 raise NameError 100 101 return tapPrintLine102 103 #tapLine to result 104 def tapLine2result(self , tapLine): 105 result = []106 pattern = re.compile(r'(\s+$)|(^\s+)')107 108 if re.match('^ok', tapLine) : 109 message = re.search(r'(?<=-)(.*)', tapLine).group()110 message = pattern.sub('', message)111 result = [TAP_OK,message] 112 elif re.match('^not.*#\sSKIP\s.*', tapLine):113 message = re.search(r'(?<=-)(.*)(?=#)', tapLine).group()114 message = pattern.sub('', message) 115 result = [TAP_SKIP,message]116 elif re.match('^not.*#\sTODO\s.*', tapLine):117 message = re.search(r'(?<=-)(.*)(?=#)', tapLine).group()118 message = pattern.sub('', message)119 result = [TAP_TODO,message]120 elif re.match('^not',tapLine):121 message = re.search(r'(?<=-)(.*)', tapLine).group()122 message = pattern.sub('', message)123 result = [TAP_NG,message]124 else:125 raise NameError126 127 return result128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 ...
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!!