diff --git a/doc/source/tools.rst b/doc/source/tools.rst
index f9cf05de0b6fa6f4f3a3e69b1e1abf90acc33145..048d5c7d3c0f9548afc17e485e2427e3d3f5ae37 100644
--- a/doc/source/tools.rst
+++ b/doc/source/tools.rst
@@ -98,8 +98,7 @@ Testing
     The following two environment variables are also supported to control
     device/platform choice::
 
-        PYOPENCL_TEST_PLATFORM_BLACKLIST=nvidia,intel
-        PYOPENCL_TEST_DEVICE_BLACKLIST=nvidia:260,intel:i5
+        PYOPENCL_TEST=0:0,1;intel=i5,i7
 
 Device Characterization
 -----------------------
diff --git a/pyopencl/tools.py b/pyopencl/tools.py
index 8e1accbbc0e06e6bd1caccb6cdec643719b96af6..02b43ca87e113b8e08590c18f886339b8a9c53c3 100644
--- a/pyopencl/tools.py
+++ b/pyopencl/tools.py
@@ -126,41 +126,60 @@ def pytest_generate_tests_for_pyopencl(metafunc):
         def __str__(self):
             return "<context factory for %s>" % self.device
 
-    platform_blacklist = []
-    device_blacklist = []
-
     import os
-    bl_string = os.environ.get("PYOPENCL_TEST_PLATFORM_BLACKLIST", "")
-    if bl_string:
-        platform_blacklist = [s.lower() for s in bl_string.split(",")]
-    bl_string = os.environ.get("PYOPENCL_TEST_DEVICE_BLACKLIST", "")
-    if bl_string:
-        for s in bl_string.split(","):
-            vendor_name, device_name = s.split(":")
-            device_blacklist.append((vendor_name.lower(), device_name.lower()))
+    dev_string = os.environ.get("PYOPENCL_TEST", None)
+
+    def find_cl_obj(objs, identifier):
+        try:
+            num = int(identifier)
+        except Exception:
+            pass
+        else:
+            return objs[num]
+
+        found = False
+        for obj in objs:
+            if identifier.lower() in (obj.name + ' ' + obj.vendor).lower():
+                return obj
+        if not found:
+            raise RuntimeError("object '%s' not found" % identifier)
+
+    if dev_string:
+        # PYOPENCL_TEST=0:0,1;intel:i5
+
+        test_plat_and_dev = [] # list of tuples (platform, [device, device, ...])
+
+        for entry in dev_string.split(";"):
+            lhsrhs = entry.split(":")
 
-    from pytools import any
+            if len(lhsrhs) == 1:
+                platform = find_cl_obj(cl.get_platforms(), lhsrhs[0])
+                test_plat_and_dev.append((platform, platform.get_devices()))
+
+            elif len(lhsrhs) != 2:
+                raise RuntimeError("invalid syntax of PYOPENCL_TEST")
+            else:
+                plat_str, dev_strs = lhsrhs
+
+                platform = find_cl_obj(cl.get_platforms(), plat_str)
+                devs = platform.get_devices()
+                test_plat_and_dev.append(
+                        (platform, [find_cl_obj(devs, dev_id) for dev_id in dev_strs.split(",")]))
+    else:
+        test_plat_and_dev = [
+                (platform, platform.get_devices())
+                for platform in cl.get_platforms()]
 
     if ("device" in metafunc.funcargnames
             or "ctx_factory" in metafunc.funcargnames
             or "ctx_getter" in metafunc.funcargnames):
         arg_dict = {}
 
-        for platform in cl.get_platforms():
+        for platform, plat_devs in test_plat_and_dev:
             if "platform" in metafunc.funcargnames:
                 arg_dict["platform"] = platform
 
-            platform_ish = (platform.name + ' ' + platform.vendor).lower()
-            if any(bl_plat in platform_ish for bl_plat in platform_blacklist):
-                continue
-
-            for device in platform.get_devices():
-
-                device_ish = (device.name + ' ' + platform.vendor).lower()
-                if any(bl_plat in platform_ish and bl_dev in device_ish
-                        for bl_plat, bl_dev in device_blacklist):
-                    continue
-
+            for device in plat_devs:
                 if "device" in metafunc.funcargnames:
                     arg_dict["device"] = device
 
@@ -178,12 +197,7 @@ def pytest_generate_tests_for_pyopencl(metafunc):
                                 for arg, value in arg_dict.iteritems()))
 
     elif "platform" in metafunc.funcargnames:
-        for platform in cl.get_platforms():
-
-            platform_ish = (platform.name + ' ' + platform.vendor).lower()
-            if any(bl_plat in platform_ish for bl_plat in platform_blacklist):
-                continue
-
+        for platform, plat_devs in test_plat_and_dev:
             metafunc.addcall(
                     funcargs=dict(platform=platform),
                     id=str(platform))