PyTest-zelfstudie:wat is, hoe te installeren, kader, beweringen
Wat is PyTest?
PyTest is een testraamwerk waarmee gebruikers testcodes kunnen schrijven met behulp van de programmeertaal Python. Het helpt je bij het schrijven van eenvoudige en schaalbare testcases voor databases, API's of UI. PyTest wordt voornamelijk gebruikt voor het schrijven van tests voor API's. Het helpt om tests te schrijven van eenvoudige unit-tests tot complexe functionele tests.
Waarom PyTest gebruiken?
Enkele voordelen van pytest zijn
- Zeer gemakkelijk om mee te beginnen vanwege de eenvoudige en gemakkelijke syntaxis.
- Kan tests parallel uitvoeren.
- Kan een specifieke test of een subset van tests uitvoeren
- Automatisch testen detecteren
- Sla tests over
- Open source
In deze Python PyTest-tutorial leer je:
- Wat is PyTest?
- Waarom PyTest gebruiken?
- PyTest installeren
- Eerste basis PyTest
- Beweringen in PyTest
- Hoe PyTest de testbestanden en testmethoden identificeert
- Voer meerdere tests uit vanuit een specifiek bestand en meerdere bestanden
- Voer een subset van de volledige test uit met PyTest
- Voer tests parallel uit met Pytest
- Pytest-wedstrijden
- Pytest-geparametriseerde test
- Pytest Xfail / Tests overslaan
- Resultaten XML
- Pytest Framework een API testen
PyTest installeren
Hieronder volgt een proces voor het installeren van PyTest:
Stap 1) U kunt pytest installeren door
pip install pytest==2.9.1
Zodra de installatie is voltooid, kunt u deze bevestigen met door
py.test -h
Dit zal de help weergeven
Eerste basis PyTest
Nu zullen we leren hoe we Pytest kunnen gebruiken met een eenvoudig PyTest-voorbeeld.
Maak een map study_pytest. We gaan onze testbestanden in deze map maken.
Navigeer naar die map in uw opdrachtregel.
Maak een bestand met de naam test_sample1.py in de map
Voeg de onderstaande code toe en sla op
import pytest def test_file1_method1(): x=5 y=6 assert x+1 == y,"test failed" assert x == y,"test failed" def test_file1_method2(): x=5 y=6 assert x+1 == y,"test failed"
Voer de test uit met het commando
py.test
U krijgt uitvoer als
test_sample1.py F. ============================================== FAILURES ======================================== ____________________________________________ test_sample1 ______________________________________ def test_file1_method1(): x=5 y=6 assert x+1 == y,"test failed" > assert x == y,"test failed" E AssertionError: test failed E assert 5 == 6 test_sample1.py:6: AssertionError
Hier in test_sample1.py F.
F zegt mislukt
Punt(.) zegt succes.
In de sectie mislukkingen kunt u de mislukte methode(s) en de foutlijn zien. Hier betekent x==y 5==6 wat niet waar is.
Vervolgens zullen we in deze PyTest-zelfstudie leren over beweringen in PyTest.
Beweringen in PyTest
Pytest-bevestigingen zijn controles die de status Waar of Onwaar retourneren. Als in Python Pytest een bewering faalt in een testmethode, wordt de uitvoering van die methode daar gestopt. De resterende code in die testmethode wordt niet uitgevoerd en de beweringen van Pytest gaan door met de volgende testmethode.
Pytest Assert-voorbeelden:
assert "hello" == "Hai" is an assertion failure. assert 4==4 is a successful assertion assert True is a successful assertion assert False is an assertion failure.
Overweeg
assert x == y,"test failed because x=" + str(x) + " y=" + str(y)
Plaats deze code in test_file1_method1() in plaats van de bewering
assert x == y,"test failed"
Het uitvoeren van de test geeft de fout als AssertionError:test failed x=5 y=6
Hoe PyTest de testbestanden en testmethoden identificeert
Standaard identificeert pytest alleen de bestandsnamen die beginnen met test_ of eindigend met _test als de testbestanden. We kunnen wel expliciet andere bestandsnamen noemen (later uitgelegd). Pytest vereist dat de namen van de testmethoden beginnen met “test .” Alle andere namen van methoden worden genegeerd, zelfs als we expliciet vragen om die methoden uit te voeren.
Bekijk enkele voorbeelden van geldige en ongeldige pytest-bestandsnamen
test_login.py - valid login_test.py - valid testlogin.py -invalid logintest.py -invalid
Opmerking:Ja, we kunnen pytest expliciet vragen om testlogin.py en logintest.py te kiezen
Bekijk enkele voorbeelden van geldige en ongeldige pytest-testmethoden
def test_file1_method1(): - valid def testfile1_method1(): - valid def file1_method1(): - invalid
Opmerking:zelfs als we file1_method1() expliciet vermelden, zal pytest deze methode niet uitvoeren.
Voer meerdere tests uit vanuit een specifiek bestand en meerdere bestanden
Momenteel hebben we in de map study_pytest een bestand test_sample1.py. Stel dat we meerdere bestanden hebben, bijvoorbeeld test_sample2.py, test_sample3.py. Om alle tests van alle bestanden in de map en submappen uit te voeren, hoeven we alleen de opdracht pytest uit te voeren.
py.test
Hierdoor worden alle bestandsnamen die beginnen met test_ en de bestandsnamen die eindigen op _test in die map en submappen onder die map uitgevoerd.
Om alleen tests uit te voeren vanuit een specifiek bestand, kunnen we py.test
py.test test_sample1.py
Voer een subset van de volledige test uit met PyTest
Soms willen we niet de hele testsuite draaien. Met Pytest kunnen we specifieke tests uitvoeren. We kunnen het op 2 manieren doen
- Groepering van testnamen op subtekenreeksovereenkomst
- Groepering van tests op markeringen
We hebben al test_sample1.py. Maak een bestand test_sample2.py en voeg de onderstaande code eraan toe
def test_file2_method1(): x=5 y=6 assert x+1 == y,"test failed" assert x == y,"test failed because x=" + str(x) + " y=" + str(y) def test_file2_method2(): x=5 y=6 assert x+1 == y,"test failed"
Dus we hebben momenteel
- test_sample1.py
- test_file1_method1()
- test_file1_method2()
- test_sample2.py
- test_file2_method1()
- test_file2_method2()
Optie 1) Voer tests uit door subtekenreeksen te matchen
Hier om alle tests uit te voeren met methode1 in de naam die we moeten uitvoeren
py.test -k method1 -v -k <expression> is used to represent the substring to match -v increases the verbosity
Dus het uitvoeren van py.test -k method1 -v geeft je het volgende resultaat
test_sample2.py::test_file2_method1 FAILED test_sample1.py::test_file1_method1 FAILED ============================================== FAILURES ============================================== _________________________________________ test_file2_method1 _________________________________________ def test_file2_method1(): x=5 y=6 assert x+1 == y,"test failed" > assert x == y,"test failed because x=" + str(x) + " y=" + str(y) E AssertionError: test failed because x=5 y=6 E assert 5 == 6 test_sample2.py:5: AssertionError _________________________________________ test_file1_method1 _________________________________________ @pytest.mark.only def test_file1_method1(): x=5 y=6 assert x+1 == y,"test failed" > assert x == y,"test failed because x=" + str(x) + " y=" + str(y) E AssertionError: test failed because x=5 y=6 E assert 5 == 6 test_sample1.py:8: AssertionError ================================= 2 tests deselected by '-kmethod1' ================================== =============================== 2 failed, 2 deselected in 0.02 seconds ===============================
Hier zie je tegen het einde 2 tests gedeselecteerd door '-kmethod1' welke zijn test_file1_method2 en test_file2_method2
Probeer te rennen met verschillende combinaties zoals:-
py.test -k method -v - will run all the four methods py.test -k methods -v – will not run any test as there is no test name matches the substring 'methods'
Optie 2) Voer tests uit met markeringen
Met Pytest kunnen we verschillende attributen voor de testmethoden instellen met behulp van pytest-markeringen, @pytest.mark . Om markeringen in het testbestand te gebruiken, moeten we pytest importeren in de testbestanden.
Hier zullen we verschillende markernamen toepassen op testmethoden en specifieke tests uitvoeren op basis van markernamen. We kunnen de markeringen op elke testnaam definiëren met behulp van
@pytest.mark.<name>.
We definiëren markeringen set1 en set2 op de testmethoden, en we zullen de test uitvoeren met behulp van de markeringsnamen. Werk de testbestanden bij met de volgende code
test_sample1.py
import pytest @pytest.mark.set1 def test_file1_method1(): x=5 y=6 assert x+1 == y,"test failed" assert x == y,"test failed because x=" + str(x) + " y=" + str(y) @pytest.mark.set2 def test_file1_method2(): x=5 y=6 assert x+1 == y,"test failed"
test_sample2.py
import pytest @pytest.mark.set1 def test_file2_method1(): x=5 y=6 assert x+1 == y,"test failed" assert x == y,"test failed because x=" + str(x) + " y=" + str(y) @pytest.mark.set1 def test_file2_method2(): x=5 y=6 assert x+1 == y,"test failed"
We kunnen de gemarkeerde test uitvoeren door
py.test -m <name> -m <name> mentions the marker name
Voer py.test -m set1 uit. Hiermee worden de methoden test_file1_method1, test_file2_method1, test_file2_method2 uitgevoerd.
Als u py.test -m set2 uitvoert, wordt test_file1_method2 uitgevoerd.
Voer tests parallel uit met Pytest
Gewoonlijk heeft een testsuite meerdere testbestanden en honderden testmethoden die een aanzienlijke hoeveelheid tijd in beslag nemen om uit te voeren. Met Pytest kunnen we tests parallel uitvoeren.
Daarvoor moeten we eerst pytest-xdist installeren door
. uit te voerenpip install pytest-xdist
U kunt nu tests uitvoeren door
py.test -n 4
-n
Pytest-wedstrijden
Fixtures worden gebruikt wanneer we code willen uitvoeren voor elke testmethode. Dus in plaats van dezelfde code in elke test te herhalen, definiëren we armaturen. Gewoonlijk worden armaturen gebruikt om databaseverbindingen te initialiseren, de basis door te geven, enz.
Een methode wordt gemarkeerd als een Pytest-fixture door te markeren met
@pytest.fixture
Een testmethode kan een Pytest-fixture gebruiken door de fixture als invoerparameter te vermelden.
Maak een nieuw bestand test_basic_fixture.py met de volgende code
import pytest @pytest.fixture def supply_AA_BB_CC(): aa=25 bb =35 cc=45 return [aa,bb,cc] def test_comparewithAA(supply_AA_BB_CC): zz=35 assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed" def test_comparewithBB(supply_AA_BB_CC): zz=35 assert supply_AA_BB_CC[1]==zz,"bb and zz comparison failed" def test_comparewithCC(supply_AA_BB_CC): zz=35 assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"
Hier
- We hebben een armatuur met de naam supply_AA_BB_CC. Deze methode retourneert een lijst met 3 waarden.
- We hebben 3 testmethoden die met elk van de waarden kunnen worden vergeleken.
Elke testfunctie heeft een invoerargument waarvan de naam overeenkomt met een beschikbare fixture. Pytest roept dan de corresponderende fixture-methode aan en de geretourneerde waarden worden opgeslagen in het invoerargument , hier de lijst [25,35,45]. Nu worden de lijstitems gebruikt in testmethoden voor de vergelijking.
Voer nu de test uit en bekijk het resultaat
py.test test_basic_fixture
test_basic_fixture.py::test_comparewithAA FAILED test_basic_fixture.py::test_comparewithBB PASSED test_basic_fixture.py::test_comparewithCC FAILED ============================================== FAILURES ============================================== _________________________________________ test_comparewithAA _________________________________________ supply_AA_BB_CC = [25, 35, 45] def test_comparewithAA(supply_AA_BB_CC): zz=35 > assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed" E AssertionError: aa and zz comparison failed E assert 25 == 35 test_basic_fixture.py:10: AssertionError _________________________________________ test_comparewithCC _________________________________________ supply_AA_BB_CC = [25, 35, 45] def test_comparewithCC(supply_AA_BB_CC): zz=35 > assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed" E AssertionError: cc and zz comparison failed E assert 45 == 35 test_basic_fixture.py:16: AssertionError ================================= 2 failed, 1 passed in 0.05 seconds =================================
De test test_comparewithBB is geslaagd sinds zz=BB=35, en de overige 2 tests zijn mislukt.
De fixture-methode heeft alleen een scope binnen dat testbestand dat het is gedefinieerd. Als we proberen toegang te krijgen tot de fixture in een ander testbestand, krijgen we een foutmelding met de melding dat fixture ‘supply_AA_BB_CC’ niet gevonden voor de testmethoden in andere bestanden.
Om dezelfde fixture tegen meerdere testbestanden te gebruiken, zullen we fixture-methoden maken in een bestand met de naam conftest.py.
Laten we dit bekijken aan de hand van het onderstaande PyTest-voorbeeld. Maak 3 bestanden conftest.py, test_basic_fixture.py, test_basic_fixture2.py met de volgende code
conftest.py
import pytest @pytest.fixture def supply_AA_BB_CC(): aa=25 bb =35 cc=45 return [aa,bb,cc]
test_basic_fixture.py
import pytest def test_comparewithAA(supply_AA_BB_CC): zz=35 assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed" def test_comparewithBB(supply_AA_BB_CC): zz=35 assert supply_AA_BB_CC[1]==zz,"bb and zz comparison failed" def test_comparewithCC(supply_AA_BB_CC): zz=35 assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"
test_basic_fixture2.py
import pytest def test_comparewithAA_file2(supply_AA_BB_CC): zz=25 assert supply_AA_BB_CC[0]==zz,"aa and zz comparison failed" def test_comparewithBB_file2(supply_AA_BB_CC): zz=25 assert supply_AA_BB_CC[1]==zz,"bb and zz comparison failed" def test_comparewithCC_file2(supply_AA_BB_CC): zz=25 assert supply_AA_BB_CC[2]==zz,"cc and zz comparison failed"
pytest zoekt eerst naar de fixture in het testbestand en als het niet wordt gevonden, zoekt het in de conftest.py
Voer de test uit met py.test -k test_comparewith -v om het resultaat te krijgen zoals hieronder
test_basic_fixture.py::test_comparewithAA FAILED test_basic_fixture.py::test_comparewithBB PASSED test_basic_fixture.py::test_comparewithCC FAILED test_basic_fixture2.py::test_comparewithAA_file2 PASSED test_basic_fixture2.py::test_comparewithBB_file2 FAILED test_basic_fixture2.py::test_comparewithCC_file2 FAILED
Pytest-geparametriseerde test
Het doel van het parametriseren van een test is om een test uit te voeren tegen meerdere sets argumenten. We kunnen dit doen door @pytest.mark.parametrize.
We zullen dit zien met het onderstaande PyTest-voorbeeld. Hier zullen we 3 argumenten doorgeven aan een testmethode. Deze testmethode voegt de eerste 2 argumenten toe en vergelijkt deze met het 3e argument.
Maak het testbestand test_addition.py met de onderstaande code
import pytest @pytest.mark.parametrize("input1, input2, output",[(5,5,10),(3,5,12)]) def test_add(input1, input2, output): assert input1+input2 == output,"failed"
Hier accepteert de testmethode 3 argumenten:input1, input2, output. Het voegt input1 en input2 toe en vergelijkt met de output.
Laten we de test uitvoeren met py.test -k test_add -v en het resultaat bekijken
test_addition.py::test_add[5-5-10] PASSED test_addition.py::test_add[3-5-12] FAILED ============================================== FAILURES ============================================== __________________________________________ test_add[3-5-12] __________________________________________ input1 = 3, input2 = 5, output = 12 @pytest.mark.parametrize("input1, input2, output",[(5,5,10),(3,5,12)]) def test_add(input1, input2, output): > assert input1+input2 == output,"failed" E AssertionError: failed E assert (3 + 5) == 12 test_addition.py:5: AssertionError
U kunt zien dat de tests 2 keer zijn uitgevoerd - een keer 5+5 ==10 en een ander 3+5 ==12
test_addition.py::test_add[5-5-10] GESLAAGD
test_addition.py::test_add[3-5-12] MISLUKT
Pytest Xfail / Tests overslaan
Er zullen zich situaties voordoen waarin we een test niet willen uitvoeren, of een testcase niet relevant is voor een bepaalde tijd. In die situaties hebben we de mogelijkheid om de test te Xfailen of de tests over te slaan
De xfailed-test wordt uitgevoerd, maar wordt niet geteld als een mislukte test of een geslaagde test. Er wordt geen traceback weergegeven als die test mislukt. We kunnen tests laten mislukken met
@pytest.mark.xfail.
Het overslaan van een test betekent dat de test niet wordt uitgevoerd. We kunnen tests overslaan met
@pytest.mark.skip.
Bewerk de test_addition.py met de onderstaande code
import pytest @pytest.mark.skip def test_add_1(): assert 100+200 == 400,"failed" @pytest.mark.skip def test_add_2(): assert 100+200 == 300,"failed" @pytest.mark.xfail def test_add_3(): assert 15+13 == 28,"failed" @pytest.mark.xfail def test_add_4(): assert 15+13 == 100,"failed" def test_add_5(): assert 3+2 == 5,"failed" def test_add_6(): assert 3+2 == 6,"failed"
Hier
- test_add_1 en test_add_2 worden overgeslagen en worden niet uitgevoerd.
- test_add_3 en test_add_4 zijn mislukt. Deze tests worden uitgevoerd en maken deel uit van xfailed(on test failure) of xpassed(on test pass) tests. Er is geen traceerbaarheid voor fouten.
- test_add_5 en test_add_6 worden uitgevoerd en test_add_6 rapporteert een storing met traceback terwijl de test_add_5 slaagt
Voer de test uit met py.test test_addition.py -v en bekijk het resultaat
test_addition.py::test_add_1 SKIPPED test_addition.py::test_add_2 SKIPPED test_addition.py::test_add_3 XPASS test_addition.py::test_add_4 xfail test_addition.py::test_add_5 PASSED test_addition.py::test_add_6 FAILED ============================================== FAILURES ============================================== _____________________________________________ test_add_6 _____________________________________________ def test_add_6(): > assert 3+2 == 6,"failed" E AssertionError: failed E assert (3 + 2) == 6 test_addition.py:24: AssertionError ================ 1 failed, 1 passed, 2 skipped, 1 xfailed, 1 xpassed in 0.07 seconds =================
Resultaten XML
We kunnen testresultaten maken in XML-formaat die we kunnen doorsturen naar Continuous Integration-servers voor verdere verwerking en zo. Dit kan gedaan worden door
py.test test_sample1.py -v –junitxml=”result.xml”
De result.xml registreert het resultaat van de testuitvoering. Vind hieronder een voorbeeld van result.xml
<?xml version="1.0" encoding="UTF-8"?> <testsuite errors="0" failures="1" name="pytest" skips="0" tests="2" time="0.046"> <testcase classname="test_sample1" file="test_sample1.py" line="3" name="test_file1_method1" time="0.001384973526"> <failure message="AssertionError:test failed because x=5 y=6 assert 5 ==6"> @pytest.mark.set1 def test_file1_method1(): x=5 y=6 assert x+1 == y,"test failed" > assert x == y,"test failed because x=" + str(x) + " y=" + str(y) E AssertionError: test failed because x=5 y=6 E assert 5 == 6 test_sample1.py:9: AssertionError </failure> </testcase> <testcase classname="test_sample1" file="test_sample1.py" line="10" name="test_file1_method2" time="0.000830173492432" /> </testsuite>
Van
Pytest Framework een API testen
Nu gaan we een klein pytest-framework maken om een API te testen. De hier gebruikte API is gratis van https://reqres.in/. Deze website is alleen bedoeld om een testbare API te bieden. Deze website slaat onze gegevens niet op.
Hier zullen we enkele tests schrijven voor
- sommige gebruikers vermelden
- aanmelden met gebruikers
Maak de onderstaande bestanden met de gegeven code
conftest.py – een armatuur hebben die de basis-URL levert voor alle testmethoden
import pytest @pytest.fixture def supply_url(): return "https://reqres.in/api"
test_list_user.py – bevat de testmethoden voor het vermelden van geldige en ongeldige gebruikers
- test_list_valid_user test voor geldig ophalen van gebruikers en verifieert het antwoord
- test_list_invaliduser test op ongeldige gebruiker ophalen en verifieert de reactie
import pytest import requests import json @pytest.mark.parametrize("userid, firstname",[(1,"George"),(2,"Janet")]) def test_list_valid_user(supply_url,userid,firstname): url = supply_url + "/users/" + str(userid) resp = requests.get(url) j = json.loads(resp.text) assert resp.status_code == 200, resp.text assert j['data']['id'] == userid, resp.text assert j['data']['first_name'] == firstname, resp.text def test_list_invaliduser(supply_url): url = supply_url + "/users/50" resp = requests.get(url) assert resp.status_code == 404, resp.text
test_login_user.py – bevat testmethoden voor het testen van de inlogfunctionaliteit.
- test_login_valid test de geldige inlogpoging met e-mail en wachtwoord
- test_login_no_password test de ongeldige inlogpoging zonder het wachtwoord door te geven
- test_login_no_email test de ongeldige inlogpoging zonder e-mail door te geven.
import pytest import requests import json def test_login_valid(supply_url): url = supply_url + "/login/" data = {'email':'[email protected]','password':'something'} resp = requests.post(url, data=data) j = json.loads(resp.text) assert resp.status_code == 200, resp.text assert j['token'] == "QpwL5tke4Pnpja7X", resp.text def test_login_no_password(supply_url): url = supply_url + "/login/" data = {'email':'[email protected]'} resp = requests.post(url, data=data) j = json.loads(resp.text) assert resp.status_code == 400, resp.text assert j['error'] == "Missing password", resp.text def test_login_no_email(supply_url): url = supply_url + "/login/" data = {} resp = requests.post(url, data=data) j = json.loads(resp.text) assert resp.status_code == 400, resp.text assert j['error'] == "Missing email or username", resp.text
Voer de test uit met py.test -v
Zie het resultaat als
test_list_user.py::test_list_valid_user[1-George] PASSED test_list_user.py::test_list_valid_user[2-Janet] PASSED test_list_user.py::test_list_invaliduser PASSED test_login_user.py::test_login_valid PASSED test_login_user.py::test_login_no_password PASSED test_login_user.py::test_login_no_email PASSED
Werk de tests bij en probeer verschillende uitgangen
Samenvatting
In deze PyTest-zelfstudie hebben we
- Pytest installeren met pip install pytest=2.9.1
- Eenvoudig pytest-programma en voer het uit met het py.test-commando.
- Beweringen, assert x==y, zullen True of False retourneren.
- Hoe pytest testbestanden en methoden identificeert.
- Testbestanden die beginnen met test_ of eindigend met _test
- Testmethoden beginnend met test
- py.test commando zal alle testbestanden in die map en submappen uitvoeren. Om een specifiek bestand uit te voeren, kunnen we het commando py.test
- Voer een subset van testmethoden uit
- Groepering van testnamen op substring matching.py.test -k
-v voert alle tests uit met in de naam. - Voer een test uit met markeringen. Markeer de tests met @pytest.mark.
en voer de tests uit met pytest -m om tests uit te voeren die zijn gemarkeerd als . - Tests parallel uitvoeren
- Pytest-xdist installeren met pip install pytest-xdist
- Voer tests uit met py.test -n NUM waarbij NUM het aantal werkers is
- Farmatuurmethoden maken om code uit te voeren vóór elke test door de methode te markeren met @pytest.fixture
- Het bereik van een fixture-methode valt binnen het bestand dat het is gedefinieerd.
- Een fixture-methode is toegankelijk voor meerdere testbestanden door deze te definiëren in het bestand conftest.py.
- Een testmethode kan toegang krijgen tot een Pytest-fixture door deze als invoerargument te gebruiken.
- Tests parametriseren om het uit te voeren op meerdere sets invoer.
@pytest.mark.parametrize(“input1, input2, output”,[(5,5,10),(3,5,12)] )
def test_add(input1, input2, output):
beweer input1+input2 ==output,”mislukt”
voert de test uit met inputs (5,5,10) en (3 ,5,12) - Skip/xfail-tests met @pytets.mark.skip en @pytest.mark.xfail
- Maak testresultaten in XML-indeling die uitgevoerde testdetails omvat met py.test test_sample1.py -v –junitxml=”result.xml”
- Een voorbeeld van een pytest-framework om een API te testen
Python
- Hoe installeer ik WordPress op Google Cloud
- Gecodeerde UI Test Automation Framework-zelfstudie
- Wat is een netwerkbeveiligingssleutel? Hoe vind je het?
- Wat is bellen via wifi? Hoe werkt het?
- Wat is 6G en hoe snel zal het zijn?
- Een dockleveller installeren
- Gedeeltelijke ontladingstesten:wat is het en hoe werkt het
- Wat is pompcavitatie en hoe voorkom ik het?
- Wat is kopersolderen en hoe het te doen?
- Wat is een onderhoudsachterstand? Hoe het te overwinnen?
- Wat is een vacuümbuistester?