diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6abe058181730c60090b36a2ab7876fb9ac87e00
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,17 @@
+language: python
+jobs:
+  include:
+    - os: linux
+      dist: xenial
+      env: EMACS=emacs24
+    - os: linux
+      dist: bionic
+      env: EMACS=emacs25
+before_install:
+  - curl https://deb.emacsos.com/apt-pub.key | sudo apt-key add -
+  - echo 'deb http://deb.emacsos.com/ debian main' | sudo tee -a /etc/apt/sources.list
+  - sudo apt-get -q update
+  - sudo apt-get install -y $EMACS-nox make python3-pip dbus-x11 zero-pinyin-service
+  - mkdir -p ~/.emacs.d/elpa/s-1.11.0/
+  - wget -O ~/.emacs.d/elpa/s-1.11.0/s.el https://raw.githubusercontent.com/magnars/s.el/1.12.0/s.el
+script: dbus-launch make dist-check EMACS=$EMACS
diff --git a/Makefile b/Makefile
index 5bba6df5f766c57daf95df3ecc3608e6e7c85c0a..12b876527bfbf370aba3bb01fd8ab4ca472c15e3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,12 @@
 VERSION := $(shell grep 'setq zero-input-version' zero-input-framework.el | cut -d'"' -f2)
+EMACS := emacs
 
 default: dist
 #===============
 # multiple file
 #===============
 check:
-	emacs -Q --batch -l zero-input-reload-all.el -f zero-input-rebuild -l zero-input-table.el -l zero-input-table-test.el -f ert-run-tests-batch
+	$(EMACS) -Q --batch -l zero-input-reload-all.el -f zero-input-rebuild -l zero-input-table.el -l zero-input-table-test.el -f ert-run-tests-batch
 zip:
 	git archive -o zero-input-el-$(VERSION).zip --prefix=zero-input/ HEAD
 #==========================
@@ -13,15 +14,15 @@ zip:
 #==========================
 dist: dist-check
 build:
-	if [ ! -x ~/.local/bin/pytest ]; then python3 -m pip install --user pytest; fi
+	if [ ! python3 -m pytest --version ]; then python3 -m pip install --user pytest; fi
 	python3 -m pytest build.py
 	./build.py
 	sed -i "s/PKG_VERSION/$(VERSION)/g" zero-input.el
 dist-check: build
 	@echo "testing byte-compile is clean..."
-	emacs -Q --batch -l ~/.emacs.d/elpa/s-1.11.0/s.el --eval='(byte-compile-file "zero-input.el")'
+	$(EMACS) -Q --batch -l ~/.emacs.d/elpa/s-1.11.0/s.el --eval='(byte-compile-file "zero-input.el")'
 	@echo "running unit tests..."
-	emacs -Q --batch -l ~/.emacs.d/elpa/s-1.11.0/s.el -l zero-input.el -l zero-input-panel-test.el -l zero-input-pinyin-service-test.el -l zero-input-framework-test.el -l zero-input-pinyin-test.el -l zero-input-table.el -l zero-input-table-test.el -f ert-run-tests-batch
+	$(EMACS) -Q --batch -l ~/.emacs.d/elpa/s-1.11.0/s.el -l zero-input.el -l zero-input-panel-test.el -l zero-input-pinyin-service-test.el -l zero-input-framework-test.el -l zero-input-pinyin-test.el -l zero-input-table.el -l zero-input-table-test.el -f ert-run-tests-batch-and-exit
 #====================
 # other make targets
 #====================
diff --git a/operational b/operational
index f55ec8e9220cb45d3ce46baca8097d5733e6026f..f89fc26f75202d5336060661137f00f74a560933 100644
--- a/operational
+++ b/operational
@@ -1,6 +1,6 @@
 * COMMENT -*- mode: org -*-
 #+Date: 2019-10-08
-Time-stamp: <2020-02-20>
+Time-stamp: <2020-02-21>
 #+STARTUP: content
 * notes                                                               :entry:
 ** 2019-04-01 zero-el a Chinese IM framework in emacs; FSM              :doc:
@@ -110,15 +110,98 @@ cd ~/lisp/elisp/zero/
 ** 2019-10-10 documents
 - Using of D-Bus
   https://www.gnu.org/software/emacs/manual/html_mono/dbus.html
+- Travis CI
+  The Ubuntu 18.04 Build Environment - Travis CI
+  https://docs.travis-ci.com/user/reference/bionic/
+  Installing Dependencies - Travis CI
+  https://docs.travis-ci.com/user/installing-dependencies
+  Customizing the Build - Travis CI
+  https://docs.travis-ci.com/user/customizing-the-build#build-matrix
 
 * later                                                               :entry:
 * current                                                             :entry:
 ** 
-** 2020-02-20 integrate travis CI support.
-just run "make dist-check".
+** 2020-02-21 zero-pinyin-service and zero-panel should recommend or suggest dbus pkg.
+I don't know it should recommend or suggest.
 ** 2019-10-23 checkdoc and package-lint can't ignore some non-issues.
 I can't run them in git pre-commit hook.
 * done                                                                :entry:
+** 2020-02-20 integrate travis CI support.
+just run "make dist-check".
+
+- problems
+  - how to run on both debian 9, 10 and ubuntu 18.04?
+
+    The Ubuntu 18.04 Build Environment - Travis CI
+    https://docs.travis-ci.com/user/reference/bionic/
+    There is no debian image on Travis CI.
+
+  - how to install s pkg when run on travis CI?
+    if ~/.emacs.d/elpa/s-1.11.0/s.el doesn't exist, install s and load it first.
+
+    how to use package-install with package-desc?
+
+    (package-install "s")
+    (package-install "s-1.12.0")
+
+    search: (error "Package `s-' is unavailable")
+
+    Package 's-' is unavailable · Issue #373 · cask/cask
+    https://github.com/cask/cask/issues/373
+
+    elisp - Emacs's package-install inserts an extra dash at the end of the package - Stack Overflow
+    https://stackoverflow.com/questions/36338528/emacss-package-install-inserts-an-extra-dash-at-the-end-of-the-package
+    wat?
+    I don't think this is the problem. In my setup, melpa is not the first element.
+
+    I will cheat. Just download the file from github when run on travis CI.
+    https://github.com/magnars/s.el
+
+  - how to run it on emacs24, emacs25, emacs26?
+    emacs24-nox is on xenial 16.04
+    emacs25-nox is on bionic 18.04
+    emacs26 is not in ubuntu yet.
+
+    How to Install GNU Emacs 26.1 in Ubuntu 18.04, 16.04, 18.10 | UbuntuHandbook
+    http://ubuntuhandbook.org/index.php/2019/02/install-gnu-emacs-26-1-ubuntu-18-04-16-04-18-10/
+    https://launchpad.net/~kelleyk/+archive/ubuntu/emacs
+    sudo add-apt-repository ppa:kelleyk/emacs
+    sudo apt update
+    sudo apt install emacs26
+    I will ignore emacs26 for now.
+
+  - travis forces venv, doesn't allow install to user site-packages.
+
+    https://docs.travis-ci.com/user/languages/python/
+    to use --user you just need to not use "language: python".
+    I will use language: python and fix the command.
+
+  - DONE elisp tests need access to GetCandidatesV2 dbus method.
+    zero-input-pinyin-service-get-candidates
+    why?
+
+    this is good. I can install the deb in travis container.
+
+  - DONE emacs run ert test doesn't exit with non-zero code when there are errors.
+    it needs a wrapper function.
+
+    ert-run-tests-batch
+    Returns the stats object.
+    ert-run-tests-batch-and-exit
+    nice.
+
+  - travis: no access to session bus.
+    how to start dbus session bus when x is not running?
+    search: travis start dbus session bus
+
+    Testing with PulseAudio server in Travis · Issue #20 · favonia/pulse
+    https://github.com/favonia/pulse/issues/20
+
+  - MOVED zero-pinyin-service and zero-panel should recommend or suggest dbus pkg.
+    I don't know it should recommend or suggest.
+
+  - travis CI test works. great. integrate to master branch.
+
 ** 2020-02-20 add github issue system support.
 - create issue templates online. then merge into master.
   git remote add github git@github.com:sylecn/zero-el.git
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e079f8a6038dd2dc8512967540f96ee0de172067
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+pytest