-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #523 from worldpeace-germany/main
Enhancements for dynamic values in shows
- Loading branch information
Showing
191 changed files
with
14,802 additions
and
240 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
|
||
# How to run MPF unittests | ||
|
||
Once MPF is installed, you can run some automated tests to make sure that everything is working. To do this, open a command prompt, and then type the following command and then press <enter>: | ||
|
||
``` | ||
python3 -m unittest discover mpf/tests | ||
``` | ||
|
||
When you do this, you should see a bunch of dots on the screen (one for each test that’s run), and then when it’s done, you should see a message showing how many tests were run and that they were successful. The whole process should take less a minute or so. | ||
|
||
(If you see any messages about some tests taking more than 0.5s, that’s ok.) | ||
|
||
The important thing is that when the tests are done, you should have a message like this: | ||
|
||
``` | ||
Ran 587 tests in 27.121s | ||
OK | ||
C:\> | ||
``` | ||
|
||
Note that the number of tests is changing all the time, so it probably won’t be exactly 587. And also the time they took to run will be different depending on how fast your computer is. | ||
|
||
These tests are the actual tests that the developers of MPF use to test MPF itself. We wrote all these tests to make sure that updates and changes we add to MPF don’t break things. :) So if these tests pass, you know your MPF installation is solid. | ||
|
||
Remember though that MPF is actually two separate parts, the MPF game engine and the MPF media controller. The command you run just tested the game engine, so now let’s test the media controller. To do this, run the following command (basically the same thing as last time but with an “mc” added to the end, like this): | ||
|
||
``` | ||
python3 -m unittest discover mpfmc/tests | ||
``` | ||
|
||
(Note that mpfmc does not have a dash in it, like it did when you installed it via pip.) | ||
|
||
When you run the MPF-MC tests, you should see a graphical window pop up on the screen, and many of the tests will put graphics and words in that window. Also, some of the tests include audio, so if your speakers are on you should hear some sounds at some point. | ||
|
||
These tests take significantly longer (maybe 8x) than the MPF tests, but when they’re done, that graphical window should close, and you’ll see all the dots in your command window and a note that all the tests were successful. | ||
|
||
Notes about the MPF-MC tests: | ||
|
||
* These tests create a window on the screen and then just re-use the same window for all tests (to save time). So don’t worry if it looks like the window content is scaled weird or blurry or doesn’t fill the entire window. | ||
* Many of these tests are used to test internal workings of the media controller itself, so there will be lots of time when the pop up window is blank or appears frozen since the tests are testing non-visual things. | ||
* The animation and transition tests include testing functionality to stop, restart, pause, and skip frames. So if things look “jerky” in the tests, don’t worry, that doesn’t mean your computer is slow, it’s just how the tests work! :) | ||
|
129 changes: 129 additions & 0 deletions
129
docs/code/Writing_Tests/WritingCustomTestsForYourMachine.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
|
||
# Writing Custom Tests for your Machine | ||
|
||
As we already mentioned, the creators of MPF are HUGE believers in the value of automated testing. To that end, MPF includes everything you need to write automated tests that test the logical functionality of your machine. These tests are extremely valuable even if your game is just based on config files. | ||
|
||
For example, you can write a test that simulates starting a game, launching a ball, hitting a sequence of switches, and then verifying that a certain mode is running, or a light is the right color, or an achievement group is in the proper state, etc. Then you can advance the time to timeout a mode and verify that the mode as stopped, etc, etc. | ||
|
||
When you first start building your MPF config, you might think, “What’s the point?”… especially with some of the more simple tests. However your MPF config files will get complex pretty quickly, and often times you’ll think you have some mode done and working perfectly, but then a month later you change something that seems unrelated which ends up breaking it. Unfortunately this usually happens without you knowing it, and by the time you realize that something broke, more times has passed and it’s hard to figure out what broke what. | ||
|
||
So this is where unit tests come in! :) | ||
|
||
If you write simple unit tests that test each new thing you add to an MPF config file, then over time you’ll end up with a huge library of tests for your game. If you get in the habit of running your tests often, then you’ll know right away if a change that you made broke something. (And you’ll also know when everything is ok when all your tests pass again!) | ||
|
||
Tutorial for writing your own tests | ||
|
||
We have a complete tutorial which walks you through writing tests for your own machine. This tutorial conveniently follows the general MPF tutorial at docs.missionpinball.org. Each step here matches the step with the same number there. (Just make sure you’ll looking at the same version of the documentation in both places.) | ||
|
||
In the general MPF tutorial, each step builds on the previous to add more features to the config files for the tutorial project. In the unit test tutorial (what you’re reading here), each step shows you how to write the unit tests which test the new features you just added to the tutorial machine. | ||
|
||
You can follow along and learn here: | ||
|
||
## Step by Step Tutorial | ||
|
||
At this point of time you should have MPF already installed and have some basic game setup. | ||
|
||
### 1. Create a “tests” folder in your machine folder | ||
|
||
First, create a folder called tests in your machine folder. This would be alongside the other folders in there, which will be “config” (created in the MPF tutorial), as well as “logs” and “data” which were created automatically by MPF the first time it ran. | ||
|
||
### 2. Add an empty `__init__.py` file | ||
|
||
Next, inside your new tests folder, create a blank file called `__init__.py`. (That’s two underscores, then the word “init”, then two more underscores, then “.py”.) This file should be totally blank. (It just needs to exist.) This file is needed to let the Python test runner find and load the tests from this folder. | ||
|
||
### 3. Add a test file | ||
|
||
Next you need to add a Python file which actually holds your tests. You can name this file whatever you want as long as it starts with “test”. (The reason for starting it with “test” is also so that the Python test runner knows that this file contains tests, allowing it to automatically find and run tests from it.) | ||
|
||
For now let’s call it test_step_2.py. | ||
|
||
Open that file and add the following lines to it: (If you are interested in what all this means, then read on below the file. Otherwise you can skip down to Step 4.) | ||
|
||
So what’s this file actually doing? | ||
|
||
The import line just imports the base class we use for MPF machine tests. (More details on that is covered in the Testing Class API page). | ||
|
||
Our specific class name TestTutorialMachine can be whatever you want. Again just make sure it starts with “Test” in order for the test runner to find out. | ||
|
||
Our specific method is called test_step_2_mpf_startup(). (Also it has to start with “test”). When the tests are run each method represents a separate “run” of MPF. The test runner will start up MPF and get it all up and running, and then it will move through the code in the test method, then it will cleanly shut down MPF when it’s done. If there are multiple test methods, then the test running will start and stop MPF multiple times. The key is that each test method is run against a “fresh” MPF copy. | ||
|
||
These test methods will also load the machine config files (just like if the command mpf was run the regular way). | ||
|
||
Anyway, in our test method, we have the only actual line that does anything: | ||
|
||
``` | ||
self.assertModeRunning('attract') | ||
``` | ||
|
||
This just tests (“asserts”) that a mode called “attract” is running. There are all sorts of MPF-specific assertion methods which we’ll cover in later steps of this tutorial. | ||
|
||
### 4. Run your test | ||
|
||
You can run your tests via the command prompt from your machine folder. (In other words, the same place where you run mpf to run your machine.) | ||
|
||
The exact command to run is `python -m unittest`. This should produce output similar to the following: | ||
|
||
``` | ||
C:\pinball\your_machine>python -m unittest | ||
C:\Python34\lib\imp.py:32: PendingDeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses | ||
PendingDeprecationWarning) | ||
. | ||
---------------------------------------------------------------------- | ||
Ran 1 test in 0.734s | ||
OK | ||
C:\pinball\your_machine> | ||
``` | ||
|
||
That warning about the deprecation can be ignored (if you even have it.. you might not). The important thing is the message towards the bottom: “Ran 1 test in 0.734s” and the “OK” below it. That means your test passed! | ||
|
||
### 5. Check out a failed test | ||
|
||
When you’re writing unit tests, you’ll end up dealing with failed tests a lot! So let’s purposefully change the test so it fails. In this case, change the line which asserts a mode called “attract” is running to look for a mode called “foo” instead, like this: | ||
|
||
``` | ||
self.assertModeRunning('foo') | ||
``` | ||
|
||
Save the file and rerun the tests and you should see results like this: | ||
|
||
``` | ||
C:\pinball\your_machine>python -m unittest | ||
C:\Python34\lib\imp.py:32: PendingDeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses | ||
PendingDeprecationWarning) | ||
F | ||
====================================================================== | ||
FAIL: test_mpf_starts (tests.test_step_2.TestTutorialMachine) | ||
Tests Step 2 of the tutorial | ||
---------------------------------------------------------------------- | ||
Traceback (most recent call last): | ||
File "C:\pinball\your_machine\tests\test_step_2.py", line 18, in test_mpf_starts | ||
self.assertModeRunning('foo') | ||
File "C:\Python34\lib\site-packages\mpf\tests\MpfTestCase.py", line 576, in assertModeRunning | ||
raise AssertionError("Mode {} not known.".format(mode_name)) | ||
AssertionError: Mode foo not known. | ||
---------------------------------------------------------------------- | ||
Ran 1 test in 0.594s | ||
FAILED (failures=1) | ||
C:\pinball\your_machine> | ||
``` | ||
|
||
Note that we see the test run failed, with one failure, and that we can scroll up and see the specific name of the test that failed along with the line that failed, and information about the failure. (In this case it tells us that the mode “foo” is not known.) | ||
|
||
So to get this test to work, you either need to change your MPF config to start a mode called “foo”, or you need to change the test back to looking for a mode called “attract”. :) | ||
|
||
### What if it didn’t work? | ||
|
||
If the unit tests don’t work for you, there are a few things you can try. | ||
|
||
If you get some kind of loading error or config error, make sure you’re running python -m unittest from your machine folder (not from the “tests” folder). | ||
|
||
If you get a message about 0 tests run, make sure you have that empty __init__.py in your tests folder. | ||
|
||
And if you get some weird error that you can’t figure out, then post a message to the MPF Google Group. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
|
||
# Automated Testing | ||
|
||
The MPF dev team are strong believers in automated testing, and we use a test-driven development (TDD) process for developing MPF itself. (At the time of this writing, there are over 800 unit tests for MPF and MPF-MC, each which contain dozens of individual tests.) | ||
|
||
We have extended Python’s built-in unittest TestCase class for MPF-specific tests, including mocking critical internal elements and adding assertion methods for MPF features. | ||
|
||
You can run built-in tests to test MPF itself or extend them if you think you found a bug or if you’re adding features to MPF. We have also built TestCase classes you can use to write unittests for your own machine. Read on for details: | ||
|
||
* [How to run MPF unittests](RunUnitTests.md) | ||
* [Writing Custom Tests for your Machine](WritingCustomTestsForYourMachine.md) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
|
||
# Config Players | ||
|
||
Config players are available as machine attributes in the form of their player name plus _player, for example, self.machine.light_player or self.machine.score_player. | ||
|
||
* [blocking_player](config_players/blocking_player.md) | ||
* [coil_player](config_players/coil_player.md) | ||
* [event_player](config_players/event_player.md) | ||
* [flasher_player](config_players/flasher_player.md) | ||
* [hardware_sound_player_player](config_players/hardware_sound_player_player.md) | ||
* [light_player](config_players/light_player.md) | ||
* [queue_event_player](config_players/queue_event_player.md) | ||
* [queue_relay_player](config_players/queue_relay_player.md) | ||
* [random_event_player](config_players/random_event_player.md) | ||
* [score_queue_player_player](config_players/score_queue_player_player.md) | ||
* [segment_display_player_player](config_players/segment_display_player_player.md) | ||
* [show_player](config_players/show_player.md) | ||
* [variable_player](config_players/variable_player.md) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Core Components | ||
|
||
Core MPF machine components, accessible to programmers at self.machine.*name*. For example, the ball controller is at self.machine.ball_controller, the event manager is self.machine.events, etc. | ||
|
||
* [auditor](core/auditor.md) | ||
* [ball_controller](core/ball_controller.md) | ||
* [device_manager](core/device_manager.md) | ||
* [events](core/events.md) | ||
* [info_lights](core/info_lights.md) | ||
* [light_controller](core/light_controller.md) | ||
* [machine](core/machine.md) | ||
* [mode_controller](core/mode_controller.md) | ||
* [placeholder_manager](core/placeholder_manager.md) | ||
* [platform_controller](core/platform_controller.md) | ||
* [service](core/service.md) | ||
* [settings](core/settings.md) | ||
* [show_controller](core/show_controller.md) | ||
* [switch_controller](core/switch_controller.md) | ||
* [switch_player](core/switch_player.md) | ||
* [text_ui](core/text_ui.md) | ||
* [twitch_bot](core/twitch_bot.md) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
|
||
# Devices | ||
|
||
Instances of MPF devices, available at self.machine.*device_collection*.*device_name*. For example, a flipper device called “right_flipper” is at self.machine.flippers.right_flipper, and a multiball called “awesome” is accessible at self.machine.multiballs.awesome. | ||
|
||
Note that device collections are accessible as attributes and items, so the right flipper mentioned above is also available to programmers at self.machine.flippers['right_flipper']. | ||
|
||
Note | ||
|
||
“Devices” in MPF are more than physical hardware devices. Many of the “game logic” components listed in the user documentation (achievements, ball holds, extra balls, etc.) are implemented as “devices” in MPF code. (So you can think of devices as being either physical or logical.) | ||
|
||
Here’s a list of all the device types in MPF, linked to their API references. | ||
|
||
* [accelerometers](devices/accelerometers.md) | ||
* [accruals](devices/accruals.md) | ||
* [achievement_groups](devices/achievement_groups.md) | ||
* [achievements](devices/achievements.md) | ||
* [autofires](devices/autofires.md) | ||
* [ball_devices](devices/ball_devices.md) | ||
* [ball_holds](devices/ball_holds.md) | ||
* [ball_routings](devices/ball_routings.md) | ||
* [ball_saves](devices/ball_saves.md) | ||
* [coils](devices/coils.md) | ||
* [combo_switches](devices/combo_switches.md) | ||
* [counters](devices/counters.md) | ||
* [digital_outputs](devices/digital_outputs.md) | ||
* [diverters](devices/diverters.md) | ||
* [dmds](devices/dmds.md) | ||
* [drop_target_banks](devices/drop_target_banks.md) | ||
* [drop_targets](devices/drop_targets.md) | ||
* [dual_wound_coils](devices/dual_wound_coils.md) | ||
* [extra_ball_groups](devices/extra_ball_groups.md) | ||
* [extra_balls](devices/extra_balls.md) | ||
* [flippers](devices/flippers.md) | ||
* [hardware_sound_systems](devices/hardware_sound_systems.md) | ||
* [kickbacks](devices/kickbacks.md) | ||
* [light_rings](devices/light_rings.md) | ||
* [light_stripes](devices/light_stripes.md) | ||
* [lights](devices/lights.md) | ||
* [magnets](devices/magnets.md) | ||
* [motors](devices/motors.md) | ||
* [multiball_locks](devices/multiball_locks.md) | ||
* [multiballs](devices/multiballs.md) | ||
* [playfield_transfers](devices/playfield_transfers.md) | ||
* [playfields](devices/playfields.md) | ||
* [psus](devices/psus.md) | ||
* [rgb_dmds](devices/rgb_dmds.md) | ||
* [score_queues](devices/score_queues.md) | ||
* [score_reel_groups](devices/score_reel_groups.md) | ||
* [score_reels](devices/score_reels.md) | ||
* [segment_displays](devices/segment_displays.md) | ||
* [sequence_shots](devices/sequence_shots.md) | ||
* [sequences](devices/sequences.md) | ||
* [servos](devices/servos.md) | ||
* [shot_groups](devices/shot_groups.md) | ||
* [shot_profiles](devices/shot_profiles.md) | ||
* [shots](devices/shots.md) | ||
* [show_queues](devices/show_queues.md) | ||
* [state_machines](devices/state_machines.md) | ||
* [steppers](devices/steppers.md) | ||
* [switches](devices/switches.md) | ||
* [timed_switches](devices/timed_switches.md) | ||
* [timers](devices/timers.md) | ||
|
||
|
37 changes: 37 additions & 0 deletions
37
docs/code/api_reference/api_reference_hardware_platforms.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
|
||
# Hardware Platforms | ||
|
||
Hardware platforms are stored in a machine hardware_platforms dictionary, for example, self.machine.hardware_platforms['fast'] or self.machine.hardware_platforms['p_roc']. | ||
|
||
* [drivers](hardware_platforms/drivers.md) | ||
* [fadecandy](hardware_platforms/fadecandy.md) | ||
* [fast](hardware_platforms/fast.md) | ||
* [i2c_servo_controller](hardware_platforms/i2c_servo_controller.md) | ||
* [light_segment_displays](hardware_platforms/light_segment_displays.md) | ||
* [lisy](hardware_platforms/lisy.md) | ||
* [mma8451](hardware_platforms/mma8451.md) | ||
* [mypinballs](hardware_platforms/mypinballs.md) | ||
* [openpixel](hardware_platforms/openpixel.md) | ||
* [opp](hardware_platforms/opp.md) | ||
* [osc](hardware_platforms/osc.md) | ||
* [p3_roc](hardware_platforms/p3_roc.md) | ||
* [p_roc](hardware_platforms/p_roc.md) | ||
* [pin2dmd](hardware_platforms/pin2dmd.md) | ||
* [pololu_maestro](hardware_platforms/pololu_maestro.md) | ||
* [pololu_tic](hardware_platforms/pololu_tic.md) | ||
* [rpi](hardware_platforms/rpi.md) | ||
* [rpi_dmd](hardware_platforms/rpi_dmd.md) | ||
* [smart_virtual](hardware_platforms/smart_virtual.md) | ||
* [smartmatrix](hardware_platforms/smartmatrix.md) | ||
* [smbus2](hardware_platforms/smbus2.md) | ||
* [snux](hardware_platforms/snux.md) | ||
* [spi_bit_bang](hardware_platforms/spi_bit_bang.md) | ||
* [spike](hardware_platforms/spike.md) | ||
* [step_stick](hardware_platforms/step_stick.md) | ||
* [system11](hardware_platforms/system11.md) | ||
* [trinamics_steprocker](hardware_platforms/trinamics_steprocker.md) | ||
* [virtual](hardware_platforms/virtual.md) | ||
* [virtual_pinball](hardware_platforms/virtual_pinball.md) | ||
* [visual_pinball_evolution](hardware_platforms/visual_pinball_evolution.md) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
|
||
# Miscellaneous Components | ||
|
||
There are several other components and systems of MPF that don’t fit into any of the other categories. Those are covered here. | ||
|
||
* [Ball Search](misc_components/BallSearch.md) | ||
* [File Manager](misc_components/FileManager.md) | ||
* [LogMixin](misc_components/LogMixin.md) | ||
* [Mode base class](misc_components/ModeBaseClass.md) | ||
* [Players](misc_components/Players.md) | ||
* [RGBAColor](misc_components/RGBAColor.md) | ||
* [RGBColor](misc_components/RGBColor.md) | ||
* [Randomizer](misc_components/Randomizer.md) | ||
* [Timers](misc_components/Timers.md) | ||
* [Utility Functions](misc_components/UtilityFunctions.md) | ||
* [data_manager](misc_components/DataManager.md) | ||
* [delay_manager](misc_components/DelayManager.md) | ||
* [delay_manager_registry](misc_components/DelayManagerRegistry.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
|
||
# Modes | ||
|
||
Covers all the “built-in” modes. They’re accessible via self.machine.modes.*name*, for example, self.machine.modes.game or self.machine.modes.base. | ||
|
||
* [attract](modes/attract.md) | ||
* [bonus](modes/bonus.md) | ||
* [carousel](modes/carousel.md) | ||
* [credits](modes/credits.md) | ||
* [game](modes/game.md) | ||
* [high_score](modes/high_score.md) | ||
* [match](modes/match.md) | ||
* [service](modes/service.md) | ||
* [tilt](modes/tilt.md) |
Oops, something went wrong.