-
Notifications
You must be signed in to change notification settings - Fork 33
Instructions on how to use? #27
Comments
Can we please have some documentation than can help people start testing mapbox their own apps? At the moment I have found nothing anywhere in mapbox that helps with testing for apps that use mapbox. I spent nearly a month struggling to get something together that would test a simple routine that used a Map, in part because there was nothing here to help me get started, which was a little frustrating. I presume that if I could work out how to use this mock it would be very useful - especially since instantiating a real Map with jsdom seems to take quite a long time, and like everyone else I like fast unit tests. So, please - may we have a little documentation ? |
Not docs, but some discussions on this subject: |
Thanks @haysclark , that was helpful. I have here laid out what I had to do to get a simple Map instantiated for a test: it may save other people time. I use jest, because it seems to give more useful error messages than mocha. But some of this applies to mocha as well. Thanks to a pointer by @fc in mapbox/mapbox-gl-js#5026 I can finally use mapbox-gl-js-mock in my tests: His PR request was merged in the current release of mapbox-gl (0.51.0) for the error:
But mapbox-gl-js-mock still depends on mapbox-gl 0.44.1 and so we still get the error. Go to line 19 where you will see this:
Change it to the following by adding the line url: 'http://localhost':
So finally I can instantiate a Map suitable for testing !
However, for those who are starting from scratch and are using ES6, you will also need to sort babel out or you will get your favourite error "unexpected token import", among others. In package.json in my dependencies I have only
I found I needed all those babel devDependencies including the babel-core with the bridge. I don't have a .babelrc file, instead I have a babel.config.js file which looks like this:
Then you will need a
You need the Incidentally the verbose key doesn't seem to have any effect whatever I do, but that's not so important. I actually have nothing in my jest.stubs.js file but you may need it one day. |
Just a footnote that my original PR was incorrect and the actual fix landed in this PR: v0.51.0 was released but mapbox-gl-js-mock still depends on 0.44.1 when you do an install (sub 1.0.0 versions don't pull in newer versions even when there is a carrot...). See here: Anyway, so I think the right fix will be to update the |
@fc thanks for the correction. I'll edit to reflect this. |
@fc I've forked the mock as you wisely suggested, and it crashes with
This is because /src/util/evented.js from mapbox-gl originally exported just one object with: now it exports three separate classes, one of which is called Evented.
I'll open another issue asking for the mapbox-gl dependency to be updated (if there isn't one already open) and keep my fingers crossed. |
yarn/npm will let you install from github, so you could, in the short term, run |
@fc I'd just like to say thanks for your help ! |
@mwarren2 out of curiosity, what approach do you take with testing apps that use mapbox-gl/draw? I have a lot of trouble simulating clicks to test functionality. I end up stubbing in a lot of my own application code to get around this, which misses a lot of bugs. You may be the only person I've seen on here who has raised issue with testing. I run into a lot of problems with testing functionality that depends on these maps. Even worse, mapbox-gl-js is deprecating the private-ish |
I'm afraid I only got modest results so far testing Mapbox code. The only way (don't hold you breath) I could find to test a particular method with a click was to say (simulated code):
It works, but I don't have any method more sophisticated than that. If you're interested I have found a way finally of instantiating a real Map in a unit test using Jest (it involves a couple of smallish hacks). And this enabled me to solve a couple of long-term problems that were slowing me down. The problem is that mapbox simply hasn't got its act together at all as far as helping people run tests is concerned.
|
Thank you, @mwarren2! I'm not sure I quite follow, but it sounds like you've found a workaround here for dealing with simulated clicks. It sounds like you are triggering the callback events directly, which makes sense - that's how I've been able to handle most of it. The problem I run into is that there is a large degree of application-specific code when it comes to configuring things like mapbox-gl-draw. For example, we wire up a lot of draw's callback events to different component behaviors. These depend on certain assumptions about how draw's event system will behave in response to certain actions (clicks!). Unfortunately, triggering callbacks directly has missed a lot of problems. Once I totally missed a memory leak that deteriorated the app after subsequent invocations of draw because I was stubbing things in to trigger callbacks directly (always sanity check things). When it comes to mapbox's own testing, mapbox-gl-draw has a lot of complex examples using simulated clicks. I have tried to reverse-engineer parts of this, but it would help for a full explanation, maybe a blog post, detailing best practices and pitfalls. These tests also rightly depend on stubbing in a lot of simplified dummy data so that reasoning about screen coordinates, unprojected geographic coordinates, and so on, is a lot easier. The issue here, however, is that map.fire is (sorta) deprecated! I would lobby against its deprecation or for promoting it as a public API. Another helpful source-code-level pattern I've found is embracing dependency injection, which works well for "bindings" addons like this. You get access to the dependency's instance, of course, so you can check basic things (like whether layers were added). Spies work well here too. For the apps we build, though, the map is the main event, and it's usually couched in a lot of complementary routing logic, components, services, etc, but all of these interact with that map a lot. So we see a ton of regressions because I just can't test the darn things. I'm going to spend a few hours with a sandbox app and set up a few tests based on the patterns I see here.
I've heard of a lot of people creating their own "noop"-ish blackhole version of mapbox-gl-js (it seems like you just forked it). Maybe when you find holes in the API, they're filled in on an as-needed basis? I went down this path once but ran into some weird problems. Anyways, I will keep working on this (considering that all of our apps are map-based and need testing), and report anything useful I've found! |
@allthesignals You're way ahead of what I've done. Yes, I included some testing code directly in my app in order to test the clicks. Which is not ideal, but got the job done for now. Just for the record I'll write later exactly what I did to get a Map directly under test. You have to make a couple of small changes in mapbox-gl-js code that will get written over when you update to a new version, so essentially yes, it's a fork. I think probably deprecating map.fire can be fought against once they realise its importance for testing. |
After a little research and looking into mapbox-gl-js's own test suite, I've found it works really well if I stub in a specific method:
This way I get control over what is returned from a click and I don't have to worry about un-projecting things. This approach depends on Sinon. |
@allthesignals
Then if you are using es6 or above you want babel so you will need to do everything in my comment above from this phrase onwards: The actual test looks like this:
The first time you run it, it takes a long time. |
Not really sure how to use this plugin with Jest. I installed it and hoping the following error would go away...
TypeError: window.URL.createObjectURL is not a function
But the error still exist...
The text was updated successfully, but these errors were encountered: