Move pcbnewswig tests to pytest

This commit is contained in:
Marek Roszko 2023-05-05 20:13:08 -04:00
parent 112aa66be5
commit ca59360d9d
9 changed files with 82 additions and 162 deletions

View File

@ -142,11 +142,11 @@ fedora_report_metrics_public:
- .unit_test
- .only_code
before_script:
- if [ "$TEST" == "cli" ]; then python3 -m pip install -r qa/tests/requirements.txt; fi
- if [ "$TEST" == "cli" ] || [ "$TEST" == "python" ]; then python3 -m pip install -r qa/tests/requirements.txt; fi
parallel:
matrix:
# The name of the test without the qa_ prefix
- TEST: [python, common, gerbview, pcbnew, eeschema, kimath, sexpr, kicad2step, spice, cli]
- TEST: [python, cli, common, gerbview, pcbnew, eeschema, kimath, sexpr, kicad2step, spice]
fedora_qa_kicad:
extends: .fedora_qa

View File

@ -32,7 +32,7 @@ endif()
if( KICAD_TEST_XML_OUTPUT )
# To do this, you will need xmlrunner
set( PYTEST_ARGS_QAPYTHON --xml=${CMAKE_CURRENT_BINARY_DIR}/qapython.xunit-results.xml )
set( PYTEST_ARGS_QAPYTHON --junitxml=${CMAKE_CURRENT_BINARY_DIR}/qapython.junit-results.xml )
set( PYTEST_ARGS_QACLI --junitxml=${CMAKE_CURRENT_BINARY_DIR}/qacli.junit-results.xml )
endif()
@ -51,8 +51,8 @@ if( NOT (MSVC AND CMAKE_BUILD_TYPE STREQUAL "Debug") )
# qa_python will never work under MSVC + Debug because we only have the Release mode python.exe
# but the kicad binaries are linked to the debug mode python
# Test that runs the QA tests through scripting
add_test( NAME qa_python
COMMAND ${PYTHON_EXECUTABLE} test-pcbnewswig.py ${PYTEST_ARGS_QAPYTHON}
add_test(NAME qa_python
COMMAND ${PYTHON_EXECUTABLE} -m pytest ${CMAKE_CURRENT_SOURCE_DIR}/pcbnewswig ${PYTEST_ARGS_QACLI}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -1,17 +0,0 @@
import unittest
class TestQAWorks(unittest.TestCase):
def setUp(self):
self.pcb = None
def test_assert_true( self ):
self.assertTrue( True )
def test_assert_equal( self ):
self.assertEqual(2, 1+1)
if __name__ == '__main__':
unittest.main()

View File

@ -1,23 +1,23 @@
import code
import unittest
import pcbnew
import pdb
import pytest
class TestPCBLoad(unittest.TestCase):
def setUp(self):
class TestPCBLoad:
pcb : pcbnew.BOARD = None
def setup_method(self):
self.pcb = pcbnew.LoadBoard("../data/pcbnew/complex_hierarchy.kicad_pcb")
def test_pcb_load(self):
self.assertNotEqual(self.pcb,None)
assert self.pcb is not None
def test_pcb_track_count(self):
tracks = list(self.pcb.GetTracks())
self.assertEqual(len(tracks),361)
assert len(tracks) == 361
def test_pcb_modules(self):
modules = list(self.pcb.GetFootprints())
self.assertEqual(len(modules), 72)
assert len(modules) == 72
def test_pcb_module_references(self):
board_refs = list(module.GetReference() for
@ -35,10 +35,10 @@ class TestPCBLoad(unittest.TestCase):
u'R26', u'R27', u'R28']
for ref in known_refs:
self.assertTrue(ref in board_refs)
assert ref in board_refs
def test_pcb_netcount(self):
self.assertEqual(self.pcb.GetNetCount(),51)
assert self.pcb.GetNetCount() == 51
def test_pcb_shapes(self):
drawings = list(self.pcb.GetDrawings())
@ -50,7 +50,7 @@ class TestPCBLoad(unittest.TestCase):
[[188595000, 51816000], [188595000, 131826000]],
[[188595000, 131826000], [88265000, 131826000]]
]
self.assertEqual(sorted(coordinates), sorted(expected_coordinates))
assert sorted(coordinates) == sorted(expected_coordinates)
def test_pcb_text(self):
drawings = list(self.pcb.GetDrawings())
@ -61,12 +61,6 @@ class TestPCBLoad(unittest.TestCase):
u'Actionneur\nPiezo New Amp\nV02')
def verify_text(self, text, x, y, layer, s):
self.assertEquals(list(text.GetPosition()), [x, y])
self.assertEquals(text.GetLayer(), layer)
self.assertEquals(text.GetText(), s)
#def test_interactive(self):
# code.interact(local=locals())
if __name__ == '__main__':
unittest.main()
assert list(text.GetPosition()) == [x, y]
assert text.GetLayer() == layer
assert text.GetText() == s

View File

@ -1,8 +1,6 @@
import code
import unittest
import pytest
import os
import pcbnew
import pdb
import tempfile
@ -14,9 +12,10 @@ B_CU = 'B.Cu'
NEW_NAME = 'My_Fancy_Layer_Name'
class TestBoardClass(unittest.TestCase):
class TestBoardClass:
pcb : pcbnew.BOARD = None
def setUp(self):
def setup_method(self):
self.pcb = LoadBoard("../data/pcbnew/complex_hierarchy.kicad_pcb")
self.TITLE="Test Board"
self.COMMENT1="For load/save test"
@ -24,20 +23,20 @@ class TestBoardClass(unittest.TestCase):
def test_pcb_find_module(self):
module = self.pcb.FindFootprintByReference('P1')
self.assertEqual(module.GetReference(),'P1')
assert module.GetReference() =='P1'
def test_pcb_get_track_count(self):
pcb = BOARD()
self.assertEqual(pcb.Tracks().size(),0)
assert pcb.Tracks().size() == 0
track0 = PCB_TRACK(pcb)
pcb.Add(track0)
self.assertEqual(pcb.Tracks().size(),1)
assert pcb.Tracks().size() == 1
track1 = PCB_TRACK(pcb)
pcb.Add(track1)
self.assertEqual(pcb.Tracks().size(),2)
assert pcb.Tracks().size() == 2
def test_pcb_bounding_box(self):
pcb = BOARD()
@ -55,8 +54,8 @@ class TestBoardClass(unittest.TestCase):
height, width = ToMM(bounding_box.GetSize())
margin = 0 # margin around bounding boxes (currently 0)
self.assertAlmostEqual(width, (30-10) + 0.5 + margin, 2)
self.assertAlmostEqual(height, (20-10) + 0.5 + margin, 2)
assert width == pytest.approx((30-10) + 0.5 + margin, 2)
assert height == pytest.approx((20-10) + 0.5 + margin, 2)
def test_pcb_get_pad(self):
pcb = BOARD()
@ -80,35 +79,35 @@ class TestBoardClass(unittest.TestCase):
# TODO: get pad == p1 evaluated as true instead
# of relying in the internal C++ object pointer
self.assertEqual(pad.this, p1.this)
self.assertEqual(pad.this, p2.this)
self.assertEqual(pad.this, p3.this)
assert pad.this == p1.this
assert pad.this == p2.this
assert pad.this == p3.this
def test_pcb_save_and_load(self):
pcb = BOARD()
pcb.GetTitleBlock().SetTitle(self.TITLE)
pcb.GetTitleBlock().SetComment(0,self.COMMENT1)
result = SaveBoard(self.FILENAME,pcb)
self.assertTrue(result)
assert result
pcb2 = LoadBoard(self.FILENAME)
self.assertNotEqual(pcb2,None)
assert pcb2 is not None
tb = pcb2.GetTitleBlock()
self.assertEqual(tb.GetTitle(),self.TITLE)
self.assertEqual(tb.GetComment(0),self.COMMENT1)
assert tb.GetTitle() == self.TITLE
assert tb.GetComment(0) == self.COMMENT1
os.remove(self.FILENAME)
def test_pcb_layer_name_set_get(self):
pcb = BOARD()
pcb.SetLayerName(31, BACK_COPPER)
self.assertEqual(pcb.GetLayerName(31), BACK_COPPER)
assert pcb.GetLayerName(31) == BACK_COPPER
def test_pcb_layer_name_set_get(self):
pcb = BOARD()
pcb.SetLayerName(31, BACK_COPPER)
self.assertEqual(pcb.GetLayerName(31), BACK_COPPER)
assert pcb.GetLayerName(31) == BACK_COPPER
def test_pcb_layer_id_get(self):
pcb = BOARD()
@ -116,10 +115,10 @@ class TestBoardClass(unittest.TestCase):
pcb.SetLayerName(b_cu_id, NEW_NAME)
# ensure we can get the ID for the new name
self.assertEqual(pcb.GetLayerID(NEW_NAME), b_cu_id)
assert pcb.GetLayerID(NEW_NAME) == b_cu_id
# ensure we can get to the ID via the STD name too
self.assertEqual(pcb.GetLayerID(B_CU), b_cu_id)
assert pcb.GetLayerID(B_CU) == b_cu_id
def test_footprint_properties(self):
pcb = LoadBoard("../data/pcbnew/custom_fields.kicad_pcb")
@ -129,17 +128,10 @@ class TestBoardClass(unittest.TestCase):
'Sheet name': '',
'myfield': 'myvalue'
}
self.assertEquals(footprint.GetProperties(), expected_properties)
self.assertEquals(footprint.GetProperty('myfield'), 'myvalue')
self.assertEquals(footprint.HasProperty('myfield'), True)
self.assertEquals(footprint.HasProperty('abcd'), False)
assert footprint.GetProperties() == expected_properties
assert footprint.GetProperty('myfield') == 'myvalue'
assert footprint.HasProperty('myfield') == True
assert footprint.HasProperty('abcd') == False
footprint.SetProperty('abcd', 'efgh')
self.assertEquals(footprint.HasProperty('abcd'), True)
self.assertEquals(footprint.GetProperty('abcd'), 'efgh')
#def test_interactive(self):
# code.interact(local=locals())
if __name__ == '__main__':
unittest.main()
assert footprint.HasProperty('abcd') == True
assert footprint.GetProperty('abcd') == 'efgh'

View File

@ -1,9 +1,10 @@
import unittest
import pytest
import pcbnew
class TestPads(unittest.TestCase):
class TestPads:
pcb : pcbnew.BOARD = None
def setUp(self):
def setup_method(self):
self.pcb = pcbnew.LoadBoard("../data/pcbnew/custom_pads.kicad_pcb")
def test_custom_pads_outline(self):
@ -17,10 +18,11 @@ class TestPads(unittest.TestCase):
]]
# test accessor without layer
polygon_set = custom_pad1.GetCustomShapeAsPolygon()
self.assertEqual(expected_polygons, self.parse_polygon_set(polygon_set))
assert expected_polygons == self.parse_polygon_set(polygon_set)
# test accessor with layer
polygon_set = custom_pad1.GetCustomShapeAsPolygon(pcbnew.F_Cu)
self.assertEqual(expected_polygons, self.parse_polygon_set(polygon_set))
assert expected_polygons == self.parse_polygon_set(polygon_set)
def parse_polygon_set(self, polygon_set):
result = []

View File

@ -1,42 +1,43 @@
import unittest
import pytest
import pcbnew
class TestTracks(unittest.TestCase):
class TestTracks:
pcb : pcbnew.BOARD = None
def setUp(self):
def setup_method(self):
self.pcb = pcbnew.LoadBoard("../data/pcbnew/tracks_arcs_vias.kicad_pcb")
def test_tracks(self):
tracks = [t for t in self.pcb.Tracks() if t.GetClass() == 'PCB_TRACK']
self.assertEqual(16, len(tracks))
assert 16 == len(tracks)
track = sorted(tracks, key=lambda t: [t.GetStart()[0], t.GetStart()[1]])[0]
self.assertEqual([27000000, 27585787], [track.GetStart()[0], track.GetStart()[1]])
self.assertEqual([27000000, 26500000], [track.GetEnd()[0], track.GetEnd()[1]])
self.assertEqual(250000, track.GetWidth())
self.assertEqual('McNetty', track.GetNetname())
assert [27000000, 27585787] == [track.GetStart()[0], track.GetStart()[1]]
assert [27000000, 26500000] == [track.GetEnd()[0], track.GetEnd()[1]]
assert 250000 == track.GetWidth()
assert 'McNetty' == track.GetNetname()
dup_track = track.Duplicate()
self.assertTrue( dup_track.m_Uuid != track.m_Uuid )
assert dup_track.m_Uuid != track.m_Uuid
def test_arcs(self):
arcs = [t.Cast() for t in self.pcb.Tracks() if t.GetClass() == 'PCB_ARC']
self.assertEqual(13, len(arcs))
assert 13 == len(arcs)
arc = sorted(arcs, key=lambda t: [t.GetStart()[0], t.GetStart()[1]])[0]
self.assertEqual([29414200, 26500000], [arc.GetCenter()[0], arc.GetCenter()[1]])
self.assertEqual([1800, 2250], [round(arc.GetArcAngleStart().AsTenthsOfADegree()),
round(arc.GetArcAngleEnd().AsTenthsOfADegree())])
self.assertEqual(2414200, round(arc.GetRadius()))
assert [29414200, 26500000] == [arc.GetCenter()[0], arc.GetCenter()[1]]
assert [1800, 2250] == [round(arc.GetArcAngleStart().AsTenthsOfADegree()),
round(arc.GetArcAngleEnd().AsTenthsOfADegree())]
assert 2414200 == round(arc.GetRadius())
dup_arc = arc.Duplicate()
self.assertTrue( dup_arc.m_Uuid != arc.m_Uuid )
assert dup_arc.m_Uuid != arc.m_Uuid
def test_vias(self):
vias = [t.Cast() for t in self.pcb.Tracks() if t.GetClass() == 'PCB_VIA']
self.assertEqual(2, len(vias))
assert 2 == len(vias)
via = sorted(vias, key=lambda t: [t.GetStart()[0], t.GetStart()[1]])[0]
self.assertEqual([29000000, 41000000], [via.GetStart()[0], via.GetStart()[1]])
self.assertEqual(400000, via.GetDrillValue())
assert [29000000, 41000000] == [via.GetStart()[0], via.GetStart()[1]]
assert 400000 == via.GetDrillValue()
dup_via = via.Duplicate()
self.assertTrue( dup_via.m_Uuid != via.m_Uuid )
assert dup_via.m_Uuid != via.m_Uuid

View File

@ -1,14 +1,14 @@
"""Unit-test parts of the CONNECTIVITY_DATA Python API."""
import unittest
import pytest
import pcbnew
class TestConnectivity(unittest.TestCase):
class TestConnectivity:
"""Test that calls on BOARD.Connectivity() are functional."""
pcb : pcbnew.BOARD = None
def setUp(self):
def setup_method(self):
"""Setup shared attributes."""
self.pcb = pcbnew.LoadBoard("../data/pcbnew/complex_hierarchy.kicad_pcb")
self.connectivity = self.pcb.GetConnectivity()
@ -17,7 +17,7 @@ class TestConnectivity(unittest.TestCase):
def test_get_connectivity_returns_connectivity_data_object(self):
"""Verify: GetConnectivity() returns a CONNECTIVITY_DATA object."""
connectivity = self.pcb.GetConnectivity()
self.assertEqual(type(connectivity).__name__, "CONNECTIVITY_DATA")
assert type(connectivity).__name__ == "CONNECTIVITY_DATA"
def test_get_connected_pads_on_track_returns_iterable_of_pads(self):
"""Verify: GetConnectedPads(track) returns an iterable of pads."""
@ -25,8 +25,8 @@ class TestConnectivity(unittest.TestCase):
tracks = list(self.pcb.TracksInNet(net.GetNetCode()))
track_with_pad = tracks[1]
pads = self.connectivity.GetConnectedPads(track_with_pad)
self.assertGreater(len(pads), 0)
self.assertTrue(all(pad.GetClass() == "PAD" for pad in pads))
assert len(pads) > 0
assert all(pad.GetClass() == "PAD" for pad in pads)
def test_get_connected_tracks_returns_iterable_of_tracks(self):
"""Verify: GetConnectedTracks(track) returns an iterable of tracks."""
@ -34,7 +34,5 @@ class TestConnectivity(unittest.TestCase):
net_tracks = self.pcb.TracksInNet(net.GetNetCode())
net_track = list(net_tracks)[0]
connected_tracks = self.connectivity.GetConnectedTracks(net_track)
self.assertGreater(len(connected_tracks), 1)
self.assertTrue(
all(track.GetClass() == "PCB_TRACK" for track in connected_tracks)
)
assert len(connected_tracks) > 1
assert all(track.GetClass() == "PCB_TRACK" for track in connected_tracks)

View File

@ -1,50 +0,0 @@
import unittest
import platform
import sys
import argparse
import locale
if platform.python_version() < '2.7':
unittest = __import__('unittest2')
else:
import unittest
try:
import xmlrunner
have_xml = True
except ImportError:
have_xml = False
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='Test suit for KiCad Python functions')
parser.add_argument('--xml', action="store", type=str,
help='Output XML test results to the given directory')
args = parser.parse_args()
if args.xml and not have_xml:
print("XML test reporting not available")
print("Install the xmlrunner package.")
sys.exit(2)
# Useful in some non English installs (using a comma as load number separator) to avoid
# wxWidgets alerts when running the test code
locale.setlocale(locale.LC_ALL, 'C')
testsuite = unittest.TestLoader().discover('pcbnewswig', pattern="*.py")
if args.xml:
# Dump XML results to the right directory
runner = xmlrunner.XMLTestRunner(output=args.xml)
else:
# Use a normal text runner
runner = unittest.TextTestRunner(verbosity=100)
results = runner.run(testsuite)
# Return an error code if any of the testsuite tests fail
if not results.wasSuccessful():
sys.exit(1)