|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +author: GuillaumeGomez |
| 4 | +title: Who talked about testing? |
| 5 | +categories: [front, crates] |
| 6 | +date: 2018-05-02 00:00:45 +0000 |
| 7 | +--- |
| 8 | + |
| 9 | +Hi everyone! |
| 10 | + |
| 11 | +Today is not about a new [`gtk-rs`] release but about a new crate being released. Let me introduce to you: [`gtk-test`]! |
| 12 | + |
| 13 | +So what's the purpose of this new crate? Simply to test UIs. Currently, testing UIs is difficult, but with [`gtk-test`] you can test basically everything UI-related way more simply. |
| 14 | + |
| 15 | +Now you might wonder: how does it work? We send UI events to the window. So if your window isn't on top of all other windows, events won't work (not on your window at least). |
| 16 | + |
| 17 | +Since examples are often better than long explanations, here we go: |
| 18 | + |
| 19 | +```rust |
| 20 | +extern crate gtk; |
| 21 | +#[macro_use] |
| 22 | +extern crate gtk_test; |
| 23 | + |
| 24 | +use gtk::{Button, ButtonExt, ContainerExt, GtkWindowExt, Window, WindowType}; |
| 25 | + |
| 26 | +fn main() { |
| 27 | + gtk::init().expect("GTK init failed"); |
| 28 | + |
| 29 | + let window = Window::new(WindowType::Toplevel); |
| 30 | + let but = Button::new(); |
| 31 | + but.set_label("button"); |
| 32 | + but.connect_clicked(|b| { |
| 33 | + b.set_label("clicked!"); |
| 34 | + }); |
| 35 | + window.add(&but); |
| 36 | + window.show_all(); |
| 37 | + window.activate_focus(); // Very important on OSX! |
| 38 | + |
| 39 | + gtk_test::click(&but); |
| 40 | + gtk_test::wait(1000); // To be sure that GTK has updated the button's label. |
| 41 | + assert_label!(but, "clicked!"); |
| 42 | +} |
| 43 | +``` |
| 44 | + |
| 45 | +Easy, right? So what happened in this code? We created a button, have set a label to it, added it to a window and clicked on it. The interesting part being that the label of the button got updated when the button is clicked (which is done through `gtk_test::click(&but)`). |
| 46 | + |
| 47 | +`assert_label!(but, "clicked!")` is there to check that the event has been called and by checking if the button's label has been updated. |
| 48 | + |
| 49 | +The only downside of this example is that you have to wait for an arbitrary amount of time that the button's label has been updated through `gtk_test::wait(1000)`. Well, there's a better way of doing this actually. Let's update the above example: |
| 50 | + |
| 51 | +```rust |
| 52 | +extern crate gtk; |
| 53 | +#[macro_use] |
| 54 | +extern crate gtk_test; |
| 55 | + |
| 56 | +use gtk::{Button, ButtonExt, ContainerExt, GtkWindowExt, Window, WindowType}; |
| 57 | + |
| 58 | +fn main() { |
| 59 | + gtk::init().expect("GTK init failed"); |
| 60 | + |
| 61 | + let window = Window::new(WindowType::Toplevel); |
| 62 | + let but = Button::new(); |
| 63 | + but.set_label("button"); |
| 64 | + let observer = observer_new!(button, connect_clicked, |b| { |
| 65 | + b.set_label("clicked!"); |
| 66 | + }); |
| 67 | + window.add(&but); |
| 68 | + window.show_all(); |
| 69 | + window.activate_focus(); // Very important on OSX! |
| 70 | + |
| 71 | + gtk_test::click(&but); |
| 72 | + observer.wait(); |
| 73 | + assert_label!(but, "clicked!"); |
| 74 | +} |
| 75 | +``` |
| 76 | + |
| 77 | +Tadam! The newly created `observer` will look and ensure that the given signal has indeed been called (if not, it'll obviously get stuck at `observer.wait()`). |
| 78 | + |
| 79 | +A few other tools are available for you in order to check more UI stuff. Here's the current list of the functions (the bold ones are the ones you'll more likely use): |
| 80 | + |
| 81 | + * **click** |
| 82 | + * **double_click** |
| 83 | + * **enter_key** |
| 84 | + * **enter_keys** |
| 85 | + * find_child_by_name |
| 86 | + * find_widget_by_name |
| 87 | + * **focus** |
| 88 | + * **key_press** |
| 89 | + * **key_release** |
| 90 | + * **mouse_move** |
| 91 | + * **mouse_press** |
| 92 | + * **mouse_release** |
| 93 | + * run_loop |
| 94 | + * wait |
| 95 | + * wait_until_done |
| 96 | + * **wait_for_draw** |
| 97 | + |
| 98 | +And a few useful macros as well: |
| 99 | + |
| 100 | + * assert_label |
| 101 | + * assert_text |
| 102 | + * assert_title |
| 103 | + * observer_new |
| 104 | + |
| 105 | +And with this, I think you're ready to start adding your own UI tests. Time to thank people now, isn't it? :) |
| 106 | + |
| 107 | +First, thanks a lot to [@antoyo] for starting this project! He wrote all functions and most of the macros. Without him, this project might have never been started so thanks (again)! |
| 108 | + |
| 109 | +Also, thanks to [@sdroege] for taking a look at the code and suggesting to add a signal observer. It made the testing much smoother! |
| 110 | + |
| 111 | +We hope it'll be of great to use for you and wish you a happy coding! |
| 112 | + |
| 113 | +[`gtk-rs`]: https://gtk-rs.org |
| 114 | +[`gtk-test`]: https://github.com/gtk-rs/gtk-test |
| 115 | +[@GuillaumeGomez]: https://github.com/GuillaumeGomez |
| 116 | +[@sdroege]: https://github.com/sdroege |
| 117 | +[@antoyo]: https://github.com/antoyo |
| 118 | + |
0 commit comments