Debugging Modules

Hướng dẫn cách gỡ lỗi module khi phát triển một module nghiệp vụ trên Odoo. Odoo cung cấp các công cụ gỡ lỗi để tìm ra nguyên nhân gốc rễ của các vấn đề khác nhau. Dưới đây là các công cụ và kỹ thuật tìm kiếm lỗi thường sử dụng.

Trong phần này, chúng tôi sẽ trình bày các phần sau:

Tự động cập nhật và các tùy chọn --dev

Trong quá trình chúng ta phát triển module, thêm model, fields, views hoặc có bất kỳ sự thay đổi với các file Python chúng ta cần phải khởi động lại server. Nếu chúng ta thay đổi trong file Xml, chúng ta cần khởi động lại server và cập nhật lại module thể hiện các thay đổi đó trên giao diện người dùng. Nếu bạn phát triển một ứng dụng lớn, vấn đề này có thể gây khó chịu và tốn thời gian. Odoo cung cấp một số tùy chọn dòng lệnh, --dev, để khắc phục những vấn đề này. Tùy chọn --dev có một số giá trị khả thi và trong phần này, chúng ta sẽ tìm hiểu từng dòng lệnh trong số chúng.

Chuẩn bị

Cài đặt inotify trong môi trường nhà phát triển của bạn bằng dòng lệnh sau. Nếu không có inotify, tính năng tự động tải lại sẽ không hoạt động:

$ pip3 install inotify

Các bước thực hiện

Để kích hoạt tùy chọn dev, bạn cần sử dụng --dev=value từ dòng lệnh. Các giá trị có thể có cho tùy chọn này là all, reload, pudb | pudb | ipdb | pdb, qweb, werkzeug and xml. Hãy xem ví dụ sau để biết thêm thông tin chi tiết:

$ odoo/odoo-bin -c ~/odoo-dev/my-instance.conf --dev=all

Nếu bạn chỉ muốn sử dụng một vài tùy chọn, bạn có thể sử dụng các giá trị được phân cách bằng dấu phẩy, như dưới đây:

$ odoo/odoo-bin -c ~/odoo-dev/my-instance.conf --dev=reload,qweb

Chi tiết hoạt động

Dưới đây là tất cả các lựa chọn --dev và mục đích sử dụng:

  • reload: Bất cứ khi nào bạn thay đổi trong Python, bạn cần khởi động lại server để cập nhật lại sự thay đổi đó trong Odoo. Tùy chọn --dev=reload sẽ tự động khởi động lại server khi bạn thực hiện bất cứ thay đổi nào trong file Python. Tính năng này sẽ không hoạt động nếu bạn chưa cài đặt gói Python inotify.

  • qweb: Bạn có thể tạo các trang web động trong Odoo bằng cách sử dụng các qweb template trong phần sau về phát triển một trang web với qweb template. Bạn có thể gỡ lỗi trong qweb template bằng t-debug. Tùy chọn t-debug chỉ hoạt động nếu kích hoạt chế độ --dev=qweb. - werkzeug: Odoo sử dụng werkzeug để xử lý các yêu cầu HTTP. Tiến trình, Odoo sẽ bắt và ngăn chặn tất cả các ngoại lệ do werkzeug tạo ra. Nếu bạn dùng --dev=werkzeug, trình gỡ lỗi tương tác của werkzeug sẽ được hiển thị trên web khi có một ngoại lệ được tạo ra.

  • xml: Bất cứ khi nào bạn thay đổi trong cấu trúc view, bạn cần khởi động lại server và cập nhật module để cập nhật những thay đổi đó. Với tùy chọn --dev=xml, bạn chỉ cần tải lại Odoo từ trình duyệt. Không cần phải khởi động lại server hoặc cập nhật module.

  • pudb | wdb | ipbd | pbd: Bạn có thể sử dụng trình gỡ lỗi Python (PDB) để có thêm thông tin chi tiết về lỗi. Khi bạn sử dụng tùy chọn --dev=pdb, nó sẽ kích hoạt PDB bất cứ khi nào một ngoại lệ được tạo ra trong Odoo. Odoo hỗ trợ 4 trình gỡ lỗi Python: pudb, wdb, ipdb pdb.

  • all: Nếu bạn sử dụng --dev=all, Tất cả các tùy chọn trước đó sẽ được kích hoạt.

Lưu ý quan trọng

Nếu bạn thực hiện các thay đổi đối với cấu trúc cơ sở dữ liệu, chẳng hạn như bạn đã thêm các trường mới, tùy chọn sẽ không phản ánh những trường này trong cơ sở dữ liệu. Bạn cần cập nhật module thủ công, nó chỉ hoạt động với nghiệp vụ logic Python.

Nếu bạn thêm giao diện hoặc menu mới, tùy chọn --dev=xml sẽ không phản ánh điều này trong giao diện người dùng. Bạn cần cập nhật module theo cách thủ công. Cái này rất hữu dụng khi bạn thiết kế cấu trúc của giao diện hoặc trang web.

Người dùng đã thực hiện các thay đổi trong giao diện từ GUI, thì --dev=xml sẽ không tải XML từ file. Odoo sẽ sử dụng cấu trúc view mà người dùng thay đổi.

Tạo log server để trợ giúp các phương thức debug

Nhật ký server hữu dụng khi cố gắng tìm kiếm những gì diễn ra trong thời gian chạy trước khi xảy ra sự cố (error). Chúng cũng có thể được thêm vào để cung cấp thông tin bổ sung giải quyết vấn đề lỗi. Hướng dẫn dưới đây chỉ cho bạn cách thêm một log vào một phương thức đã tồn tại.

Chuẩn bị

Chúng ta sẽ thêm một số câu lệnh ghi log vào phương thức sau, phương thức này sẽ lưu mức tồn kho của sản phẩm vào 1 file bạn cũng cần thêm các phần phụ thuộc của sản phẩm và module kho vào file manifest:

from os.path import join
from odoo import fields, models, _
from odoo.exceptions import UserError
EXPORTS_DIR = '/home/exports'

class EducationClass(models.Model):
    _name = 'education.class'
    _description = 'Education Class'

    name = fields.Char(string='Name', required=True)

    def export_list_student_of_class(self):
        students = self.env['education.student'].search([('class_id', 'in', self.ids)])
        fname = join(EXPORTS_DIR, 'list_student.txt')
        try:
            with open(fname, 'w') as fobj:
                for student in students:
                    fobj.write('%s\t%f\n' % (student.name, student.email))
        except IOError:
            raise UserError(_"unable to save file")

Các bước thực hiện

Để nhận được một số log khi phương thức này đang thực thi, hãy thực hiện các bước sau:

  1. Khi bắt đầu code cần import thư viện logging:

    import logging
    
  2. Trước khi định nghĩa về class model, hãy lấy một logger của module:

    _logger = logging.getLogger(__name__)
    
  3. Chỉnh sửa code phương thức export_list_student_of_class(), như sau:

    def export_list_student_of_class(self):
        students = self.env['education.student'].search([('class_id', 'in', self.ids)])
        fname = join(EXPORTS_DIR, 'list_student.txt')
        try:
            with open(fname, 'w') as fobj:
                for student in students:
                    fobj.write('%s\t%f\n' % (student.name, student.email))
        except IOError:
            _logger.exception(_("Error while writing to %s in %s", 'list_student.txt', EXPORTS_DIR))
            raise UserError("unable to save file")
    

Chi tiết hoạt động

Bước 1: Nhập module logging từ thư viện của Python. Odoo sử dụng module này để quản lý log của nó.

Bước 2: Thiết lập trình ghi log module Python. Chúng ta sử dụng trường __name__ trong Odoo như một biến tự động cho tên của trình ghi và để gọi ghi log bằng _logger.

Lưu ý quan trọng

Biến __name__ được trình thông dịch Python đặt tự động tại thời điểm nhập module và giá trị của nó là tên đầy đủ của module. Vì Odoo thực hiện một thủ thuật nhỏ với việc nhập, các addons module được Python xem là thuộc về gói Python odoo.addons. Vì vậy, Nếu code nằm trong viin_education/models/education_class.py, __name__ sẽ là odoo.addons.viin_education.models.education_class.

Bằng cách này, chúng ta nhận được hai lợi ích:

  • Cấu hình ghi log toàn cục được thiết lập trên odoo logger được áp dụng cho trình ghi log của chúng ta do cấu trúc phân cấp của các trình ghi logger trong module logging.

  • Các log sẽ được bắt đầu bằng đường dẫn module chi tiết, đây là một hỗ trợ tốt khi cố gắng tìm nơi tạo ra một dòng log nhất định.

Bước 3: Sử dụng trình logger để tạo thông báo log. Các phương thức có sẵn cho việc này là (bằng cách tăng level log) debug, info, warning, errorcritical. Tất cả các phương thức này chấp nhận tham số là một thông báo, trong đó bạn có thể sử dụng % thay thế chuỗi và các đối số bổ sung để chèn vào thông báo đó. Bạn không nên tự mình thay thế %, module logging đủ hiểu để thực hiện thao tác này nếu log phải được tạo. Nếu bạn đang chạy với cấp độ log là INFO, thì log DEBUG sẽ bỏ qua việc thay thế chuỗi để tiêu tốn CPU khi chạy lâu dài.

Một phương thức hữu dụng khác được hiển thị trong công thức này là _logger.exception(), có thể được sử dụng trong một trình xử lý ngoại lệ. Thông báo sẽ được ghi lại với mức lỗi và lịch sử vết lỗi cũng được in trong log ứng dụng.

Thông tin thêm

Bạn có thể kiểm soát logging level của ứng dụng từ dòng lệnh hoặc từ file cấu hình. Có hai cách chính để làm điều này: Cách đầu tiên là sử dụng tùy chọn --log-handler. Cú pháp cơ bản của nó là như thế này: --log-handler = prefix: level. Trong trường hợp này, prefix là một đoạn đường dẫn tên của loggerlevel là DEBUG, INFO, WARNING, ERROR hoặc CRITICAL. Nếu bạn bỏ qua prefix, bạn sẽ đặt level mặc định cho tất cả các logger. Ví dụ: để đặt cấp độ logging của các logger viin_education thành DEBUG và giữ cấp độ log mặc định cho các addon khác, bạn có thể khởi động Odoo như sau:

$ python3 odoo-bin -c project.conf --log-handler=odoo.addons.viin_education:DEBUG

Có thể chỉ định --log-handler nhiều lần trên dòng lệnh. Bạn cũng có thể cấu hình trình xử log trong file cấu hình trên hệ thống Odoo của bạn. Trong trường hợp đó, bạn có thể sử dụng danh sách các cặp tiền tố: cấp được phân tách bằng dấu phẩy. Ví dụ: dòng sau là cùng một cấu hình cho đầu ra logging tối thiểu như trước. Chúng giữ nguyên các thông báo quan trọng nhất và các thông báo lỗi theo mặc định, ngoại trừ các thông báo do werkzeug tạo ra, chúng ta chỉ muốn các thông báo quan trọng và odoo.service.server, chúng ta giữ các thông báo cấp thông tin, bao gồm cả khởi động server thông báo:

log_handler = :ERROR,werkzeug:CRITICAL,odoo.service.server:INFO

Cách thứ hai là sử dụng tùy chọn --log-level. Để kiểm soát cấp độ log trên toàn hệ thống, bạn có thể sử dụng --log-level làm tùy chọn dòng lệnh. Các giá trị có thể có cho tùy chọn này là critical, error, warning, debug, debug_rpc, debug_rpc_answer, debug_sqltest. Có một số cách viết tắt để thiết lập level log. Đây là danh sách chúng:

  • --log-request viết tắt cho --log-handler = odoo.http.rpc.request: DEBUG.

  • --log-response viết tắt cho --log-handler = odoo.http.rpc.request: DEBUG.

  • --log-web viết tắt cho --log-handler = odoo.http: DEBUG.

  • --log-sql viết tắt cho --log-handler = odoo.sql_db: DEBUG.

Sử dụng trình shell Odoo để gọi phương thức tương tác

Giao diện web Odoo dành cho người dùng cuối, mặc dù chế độ nhà phát triển mở khóa một số tính năng mạnh mẽ. Tuy nhiên, testingdebugging thông qua giao diện web không phải là cách dễ nhất để thực hiện mọi việc, vì bạn cần chuẩn bị dữ liệu theo cách thủ công, điều hướng trong menu để thực hiện các tác vụ, v.v. .Odoo shell là một giao diện dòng lệnh, bạn có thể sử dụng giao diện này để thực hiện các cuộc gọi. Phần nội dung này chỉ ra cách khởi động Odoo shell và thực hiện các hành động như gọi một phương thức bên trong shell.

Chuẩn bị

Chúng ta sẽ sử dụng lại code tương tự như trong nội dung trước đó để tạo logger server để trợ giúp các phương thức debug. Điều này cho phép model product.product thêm một phương thức mới. Chúng ta sẽ giả định rằng bạn có một hệ thống với addon được cài đặt và có sẵn. Trong nội dung này, chúng tôi hy vọng rằng bạn có file cấu hình Odoo cho trường hợp này được gọi là project.conf.

Các bước thực hiện

Để gọi phương thức export_list_student_of_class() từ shell Odoo, hãy thực hiện các bước sau:

  1. Khởi động shell Odoo và chỉ định file cấu hình dự án(project.conf) của bạn:

    $ ./odoo-bin shell -c project.conf --log-level=error
    
  2. Kiểm tra thông báo lỗi và đọc văn bản thông tin được hiển thị trước dấu nhắc dòng lệnh Python thông thường:

    env: <odoo.api.Environment object at 0x7f29a29068e0>
    odoo: <module 'odoo' from '/home/work/odoo14/odoo14/odoo/__init__.py'>
    openerp: <module 'odoo' from '/home/work/odoo14/odoo14/odoo/__init__.py'>
    self: res.users(1,)
    Python 3.8.10 (default, Nov 26 2021, 20:14:08)
    [GCC 9.3.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    (Console)
    >>>
    
  3. Lấy một bản ghi thiết lập cho education.class:

    >>> list_class = env['education.class'].search([])
    >>> list_class
    education.class(1,)
    >>>
    
  4. Gọi phương thức export_list_student_of_class():

    >>> list_class.export_list_student_of_class()
    
  5. Thực hiện phiên giao dịch trước khi thoát:

    >>> env.cr.commit()
    
  6. Thoát khỏi shell bằng cách ấn Ctrl + D.

Chi tiết hoạt động

Bước 1 sử dụng odoo-bin shell bắt đầu Odoo shell. Thường tất cả các tham số dòng lệnh đều có sẵn. Chúng ta sử dụng -c để chỉ định file cấu hình và --log-level để giảm độ dài của log. Khi gỡ lỗi, bạn có thể muốn có một mức độ loggingDEBUG cho một số addon cụ thể.

Trước khi cung cấp cho bạn một giao diện dòng lệnh Python, odoo-bin shell khởi động hệ thống Odoo, không lắng nghe trên network và khởi tạo một số biến toàn cục, được đề cập trong đầu ra.

  • env là môi trường được kết nối với cơ sở dữ liệu và được chỉ định trên dòng lệnh hoặc trong file cấu hình.

  • odoo là gói odoo đã được nhập cho bạn. Bạn có thể truy cập vào tất cả các module trong gói để làm gì đó bạn mong muốn.

  • openerp là một bí danh của gói odoo để tương thích ngược.

  • self là 1 recordset của model res.users, chứa một bản ghi duy nhất là superuser của Odoo(Quản trị viên), được liên kết với môi trường env.

Bước 3 env sử dụng để lấy tập hợp bản ghi của lớp học. Bước 4 gọi phương thức của tập hợp bản ghi học sinh của model education.student. Các thao tác này bạn thực hiện giống như những gì bạn thực hiện bên trong phương thức, với một điểm khác biệt nhỏ chúng sử dụng env chứ không phải self.env. (Có thể đọc ở Basic Server-Side Development để có nhiều thông tin).

Bước 5 Thực hiện phiên giao dịch với cơ sở dữ liệu. Điều này không hoàn toàn cần thiết ở đây vì chúng ta không chỉnh sửa bất kỳ bản ghi nào trong cơ sở dữ liệu, nhưng nếu chúng ta đã làm như vậy và muốn thay đổi liên tục, thì điều là cần thiết, khi bạn sử dụng Odoo thông qua giao diện web, mỗi lệnh gọi RPC sẽ chạy trong phiên giao giao dịch với cơ sở dữ liệu của riêng nó và Odoo quản lý chúng cho bạn. Khi chạy ở chế độ shell, điều này không còn xảy ra nữa và bạn cần phải gọi env.cr.commit() hoặc env.cr.rollback(). Nếu không, khi bạn thoát khỏi shell, bất kỳ giao dịch nào đang diễn ra sẽ được tự động khôi phục lại như cũ. Khi kiểm thử, điều này là tốt, nhưng nếu bạn sử dụng shell, ví dụ, để viết kịch bản cấu hình của một hệ thống, thì đừng quên thực hiện commit công việc của bạn!

Thông tin thêm

Ở chế độ shell, theo mặc định, Odoo mở giao diện shell REPL của Python. Bạn có thể sử dụng REPL theo lựa chọn của mình bằng cách sử dụng tùy chọn --shell-interface. Các REPL được hỗ trợ là ipython, ptpython, bpythonpython:

$ ./odoo-bin shell -c project.conf --shell-interface=ptpython

Sử dụng trình gỡ lỗi Python để theo dõi việc thực thi phương thức

Đôi khi, log ứng dụng không đủ để tìm ra vấn đề gì đã xảy ra. Thật may chúng ta cũng có trình gỡ lỗi Python. Trong phần nội dung này chúng ta sẽ thấy cách chèn một điểm dừng trong phương thức và theo dõi quá trình thực thi bằng tay.

Chuẩn bị

Chúng ta sẽ sử dụng lại phương thức export_list_student_of_class() đã được sử dụng trong phần Odoo shell để gọi các phương thức một cách tương tác của phần này. Đảm bảo rằng bạn có một bản sao chép bằng tay.

  1. Chỉnh sửa lại code của phương thức và thêm dòng được đánh dấu ở dưới đây:

    def export_list_student_of_class(self):
        import pdb; pdb.set_trace()
        students = self.env['education.student'].search([('class_id', 'in', self.ids)])
        fname = join(EXPORTS_DIR, 'list_student.txt')
        try:
            with open(fname, 'w') as fobj:
                for student in students:
                    fobj.write('%s\t%f\n' % (student.name, student.email))
        except IOError:
            raise UserError(_"unable to save file")
    
  2. Chạy phương thức. Chúng ta sẽ sử dụng Odoo shell, như đã giải thích trong sử dụng Odoo shell để gọi nội dung các phương thức một cách tương tác:

    $ ./odoo-bin shell -c project.conf --log-level=error
    [...]
    >>> list_class = env['education.class'].search([])
    >>> list_class
    education.class(1,)
    >>> list_class.export_list_student_of_class()
    > /home/work/odoo14/chap7_education_doc/viin_education/models/education_class.py(18)export_list_student_of_class()
    -> students = self.env['education.student'].search([('class_id', 'in', self.ids)])
    (Pdb)
    
  3. Tại dấu nhắc (Pdb), hãy sử dụng lệnh args (phím tắt của nó là a) lấy các giá trị của các đối số đã được truyền cho phương thức:

    (Pdb) a
    self = education.class(1,)
    (Pdb)
    
  4. Khi bạn nhập lệnh list để kiểm tra vị trí code mà bạn đang đứng:

    Pdb) list
    13
    14      name = fields.Char(string='Name', required=True)
    15
    16      def export_list_student_of_class(self):
    17          import pdb; pdb.set_trace()
    18  ->        students = self.env['education.student'].search([('class_id', 'in', self.ids)])
    19          fname = join(EXPORTS_DIR, 'list_student.txt')
    20          try:
    21              with open(fname, 'w') as fobj:
    22                  for student in students:
    23
    
  5. Nhập lệnh next 3 lần qua các dòng đầu tiên của phương thức. Bạn cũng sử dụng n, là một phím tắt:

    (Pdb) n
    > /home/work/odoo14/chap7_education_doc/viin_education/models/education_class.py(19)export_list_student_of_class()
    -> fname = join(EXPORTS_DIR, 'list_student.txt')
    (Pdb) n
    > /home/work/odoo14/chap7_education_doc/viin_education/models/education_class.py(20)export_list_student_of_class()
    -> try:
    (Pdb) n
    > /home/work/odoo14/chap7_education_doc/viin_education/models/education_class.py(21)export_list_student_of_class()
    -> with open(fname, 'w') as fobj:
    (Pdb)
    
  6. Sử dụng p lệnh để hiển thị giá trị của biến studentsfname:

    (Pdb) p students
    education.student()
    (Pdb) p fname
    '/home/Desktop/exports/list_student.txt'
    (Pdb)
    
  7. Thay đổi giá trị của fname để trỏ tới thư mục /tmp:

    (Pdb) !fname = '/tmp/list_student.text'
    
  8. Sử dụng lệnh return (phím tắt: r) để thực thi hàm hiện tại:

    (Pdb) r
    --Return--
    > /home/work/odoo14/chap7_education_doc/viin_education/models/education_class.py(22)export_list_student_of_class()->None
    -> for student in students:
    (Pdb)
    
  9. Sử dụng lệnh cont (phím tắt: c) để tiếp tục thực hiện chương trình:

    (Pdb) c
    >>>
    

Chi tiết hoạt động

Trong bước 1, chúng ta đặt điểm dừng trong code của phương thức bằng cách gọi phương thức set_trace() của module pdb từ thư viện chuẩn Python. Khi phương thức này được thực thi, quy trình bình thường của chương trình sẽ dừng lại và bạn nhận được dấu nhắc lệnh (Pdb) trong đó bạn có thể nhập các lệnh pdb.

Bước 2 gọi phương thức export_list_student_of_class() bằng cách sử dụng chế độ shell. Cũng có thể khởi động lại server bình thường và sử dụng giao diện web để tạo lệnh gọi đến phương thức bạn cần theo dõi bằng cách nhấp vào các phần tử thích hợp của giao diện người dùng. Khi bạn cần thực hiện thủ công một số bước thông qua code trong trình gỡ lỗi Python, dưới đây là một số gợi ý giúp bạn gỡ lỗi một cách dễ dàng hơn.

  • Giảm level logging để tránh có quá nhiều dòng log, điều này gây rối loạn đầu ra trình gỡ lỗi. Bắt đầu ở mức ERROR nhìn chung là ổn. Nếu bạn muốn bật một số trình ghi cụ thể với độ chi tiết cao hơn, bạn có thể thực hiện điều này bằng cách sử dụng tùy chọn dòng lệnh --log-handler (tham khảo Tạo log server để trợ giúp các phương thức debug).

  • Chạy server với --workers=0 để tránh bất kỳ sự cố đa xử lý nào có thể gây ra cùng một điểm dừng hai lần trong hai quá trình khác nhau.

  • Chạy server với --max-cron-thread=0 để vô hiệu hóa quá trình xử lý các tác vụ định kỳ ir.cron, chúng có thể chạy trong khi bạn đang thực hiện gỡ lỗi, và có thể tạo ra các log và tác dụng phụ không mong muốn.

Từ bước 3 tới bước 8 sử dụng lệnh pdb để thực hiện một số phương thức. Đây là bản tóm tắt các lệnh chính của pdb. Hầu hết chúng cũng có sẵn bằng cách sử dụng chữ cái đầu tiên làm phím tắt. Chúng tôi chỉ ra điều này ở đây bằng cách cho các chữ cái tùy chọn giữa dấu ngoặc đơn:

  • h (elp): Hiển thị các trợ giúp về lệnh pdb.

  • a (rgs): Thể hiện giá trị đối số của hàm / các phương thức hiện tại.

  • l (ist): Điều này hiển thị mã nguồn code đang thực thi bao gồm 11 dòng, Lúc đầu được căn giữa ở dòng hiện tại. Các cuộc gọi kế tiếp sẽ đi sâu vào file mã nguồn. Theo tùy chọn, bạn có thể chuyển 2 số nguyên đầu và cuối, chỉ định khu vực hiển thị.

  • p: Sẽ in ra một biến.

  • pp: Sẽ in ra một biến (hữu dụng với danh sách và từ điển).

  • w (here): Hiển thị ngăn xếp cuộc gọi với dòng hiện tại ở dưới cùng và trình thông dịch Python ở trên cùng.

  • u (p): Di chuyển lên một cấp trong call stack.

  • d (own): Di chuyển xuống một cấp trong call stack.

  • n (ext): Thực thi dòng code hiện tại và sau đó stop.

  • s (tep):Đây là bước bên trong việc thực hiện một cuộc gọi phương thức.

  • r (eturn): Tiếp tục thực hiện phương thức hiện tại cho đến khi nó trở lại.

  • c (ont (inue)): Tiếp tục thực hiện chương trình cho đến khi điểm dừng tiếp theo được nhấn.

  • b (reak) <args>: Tạo ra một điểm dừng mới (new breakpoint) và hiển thị mã định danh của nó, args có thể là một trong những điều sau:

  • <empty>: Danh sách này liệt kê tất cả các điểm dừng (breakpoints).

  • line_number: Dừng ở dòng được chỉ định trong file hiện tại.

  • filename: line_number: Điều này dừng ở dòng được chỉ định của file được chỉ định (được tìm kiếm trong các thư mục của sys.path).

  • function_name: Dừng ở dòng đầu tiên của hàm được chỉ định.

  • tbreak <args>: Tương tự như break, nhưng hủy sẽ bị hủy sau khi nó đã đạt được, vì vậy việc thực hiện liên tiếp dòng sẽ không kích hoạt nó hai lần.

  • disable bp_id: Vô hiệu hóa một điểm dừng theo ID.

  • enable bl_id: Cho phép một điểm dừng bị vô hiệu hóa bởi ID.

  • j (ump) lineno: Dòng tiếp theo để thực thi sẽ là dòng được chỉ định. Điều này có thể là được sử dụng để chạy lại hoặc bỏ qua một số dòng.

  • statement: Điều này thực thi một câu lệnh Python. Các ký tự ! có thể bị bỏ qua nếu lệnh không giống lệnh pdb. Ví dụ: bạn cần nó nếu bạn muốn đặt giá trị của một biến có tên a, vì a là phím tắt cho lệnh args.

Thông tin thêm

Trong phần này, chúng ta chèn một pdb.set_trace() câu lệnh sẽ vào bên trong pdb để gỡ lỗi. Chúng ta cũng có thể bắt đầu pdb trực tiếp từ bên trong Odoo shell. Điều này rất hữu dụng khi bạn không thể dễ dàng chỉnh sửa code của dự án sử dụng pdb.runcall(). Hàm này nhận một số phương thức làm đối số đầu tiên và các đối số để truyền cho hàm làm đối số tiếp theo. Vì vậy bên trong shell odoo, bạn thực hiện điều này:

import pdb
>>> list_class = env['education.class'].search([])
>>> pdb.runcall(list_class.export_list_student_of_class)
> /home/work/odoo14/chap7_education_doc/viin_education/models/education_class.py(17)export_list_student_of_class()
-> import pdb; pdb.set_trace()
(Pdb)

Trong phần này, chúng ta tập trung vào trình gỡ lỗi Python từ thư viện tiêu chuẩn Python pdb. Rất hữu dụng khi bạn biết về công cụ này vì nó đảm bảo có sẵn trên bất kỳ phiên bản nào của Python. Có sẵn các trình gỡ lỗi khác, như ipdb (https://pypi.python.org/pypi/ipdb) and pudb (https://pypi.python.org/pypi/pudb), có thể được sử dụng để thay thế cho pdb. Chúng chia sẻ cùng một API và hầu hết các lệnh mà bạn thấy trong phần này đều không thay đổi. Ngoài ra, tất nhiên, nếu bạn phát triển Odoo bằng Python IDE, bạn sẽ có quyền truy cập vào trình gỡ lỗi được tích hợp với nó. Nếu bạn muốn tìm hiểu thêm về trình gỡ lỗi pdb, cần tham chiếu tài liệu đầy đủ của pdb tại https://docs.python.org/3.5/library/pdb.html.

Tìm hiểu về các tùy chọn chế độ debug

Trong phát triển Odoo việc bật tùy chọn debug/developer là rất cần thiết, các tùy chọn này rất hữu dụng trong việc gỡ lỗi và tiết lộ thêm một số thông tin kỹ thuật. Trong phần này, chúng ta sẽ xem xét các tùy chọn này một cách chi tiết.

Chuẩn bị

Kích hoạt chế độ phát triển.

../../_images/active_developer-01.en.jpg

Sau khi kích hoạt chế độ phát triển, bạn sẽ thấy một menu dropdown với icon con bọ ở trên cùng như hình dưới đây:

../../_images/menu_debug-02.en.jpg

Trong menu, bạn sẽ thấy các tùy chọn khác nhau. Chúng sẽ dẫn đến các hành động. Phần tiếp theo sẽ giải thích chi tiết các tùy chọn này.

Chi tiết tùy chọn

Chúng ta hãy tìm hiểm thêm về các tùy chọn sau:

  • Chạy kiểm tra JS: Tùy chọn này sẽ hướng bạn đến trang thử nghiệm QUnit JavaScript, được hiển thị trong ảnh chụp màn hình sau. Nó sẽ bắt đầu chạy tất cả từng trường hợp thử nghiệm một. Tại đây, bạn có thể xem tiến trình và trạng thái của trường thử nghiệm.

../../_images/web_tests-03.en.jpg
  • Chạy Kiểm thử Mobile JS: Tương tự như tùy chọn trước đó, nhưng tùy chọn này chạy một trường hợp thử nghiệm QUnit cho môi trường di động.

  • Chạy bấm test ở mọi nơi:: Tùy chọn bắt đầu nhấp vào từng menu một. Nó sẽ nhấp vào trong tất cả các giao diện và tìm kiếm. Nếu một cái gì đó xảy ra lỗi hoặc có bất kỳ hồi quy nào, nó sẽ hiển thị các dấu vết. Để dừng thử nghiệm này, bạn cần tải lại trang.

  • Mở giao diện: Lựa chọn Sẽ mở một danh sách tất cả các giao diện hiện có. Bằng cách chọn bất kỳ trong số chúng, bạn có thể mở giao diện đó mà không cần xác định bất kỳ menu hoặc hành động nào.

  • Disable Tours: Odoo sử dụng các chuyến tham quan để cải thiện giới thiệu người dùng mới. Nếu bạn muốn vô hiệu hóa nó, bạn có thể thực hiện bằng cách sử dụng tùy chọn này.

  • Start Tour: Odoo cũng sử dụng các chuyến tham quan để kiểm thử tự động. Tùy chọn này sẽ mở ra một hộp thoại với danh sách tất cả các chuyến tham quan, như được hiển thị trong ảnh chụp màn hình sau. Bằng cách nhấp vào nút phát bên cạnh chuyến thăm quan, Odoo sẽ tự động thực hiện tất cả các bước của chuyến tham quan:

../../_images/dialog_tours-04.en.jpg
  • Sửa hành động: Chúng ta thêm mục menu và hành động mở giao diện trong Odoo. Chi tiết của hành động này cũng được lưu trữ trong cơ sở dữ liệu dưới dạng bản ghi. Tùy chọn này sẽ mở bản ghi của hành động mà chúng ta đang xem hiện tại.

  • Xem các Trường của model: Tùy chọn này sẽ giúp bạn khi bạn muốn thấy chi tiết các trường từ giao diện người dùng. Nó sẽ hiện ra một danh sách các trường cho model hiện tại. Ví dụ, nếu bạn mở một tree hoặc form view cho model education.class, tùy chọn này sẽ hiện ra một danh sách các trường cho model education.class.

  • Quản lý Các bộ lọc: Trong Odoo, người dùng có thể tạo tùy biến bộ lọc từ search view. Tùy chọn sẽ mở một danh sách tùy biến bộ lọc cho model hiện tại. Tại đây, bạn có thể chỉnh sửa một tùy chỉnh bộ lọc.

  • Dịch kỹ thuật: Tùy chọn này sẽ mở một danh sách các thuật ngữ đã dịch cho model hiện tại. Bạn có thể chỉnh sửa các thuật ngữ dịch kỹ thuật cho model của bạn từ đây.

  • Xem trường trên giao diện: Bạn có thể mở rộng và chỉnh sửa một giao diện đã tồn tại từ các module hỗ trợ khác. Trong một số ứng dụng, các view được kế thừa bởi một số module. Bởi vì điều này, khó để có một ý tưởng rõ ràng về định nghĩa toàn bộ view. Với tùy chọn này, bạn sẽ nhận được định nghĩa giao diện cuối cùng sau khi áp dụng tất cả các giao diện. Bên trong, nó sử dụng phương thức fields_view_get().

  • Sửa Giao diện: <Loại view>: Tùy chọn này sẽ mở hộp thoại với bản ghi ir.ui.view của dạng xem hiện tại. Tùy chọn này là động và nó sẽ hiển thị một tùy chọn dựa trên giao diện hiện tại đang mở. Điều này có nghĩa là nếu bạn mở giao diện Kanban, bạn sẽ nhận được tùy chọn sửa view: tùy chọn Kanban, và nếu bạn mở Form View, bạn sẽ lấy tùy chọn sửa view: Tùy chọn form.

Tip quan trọng

Bạn có thể chỉnh sửa định nghĩa dạng view, từ tùy chọn Edit View. Định nghĩa này sẽ được cập nhật trong cơ sở dữ liệu hiện tại và những thay đổi sẽ bị xóa đi khi cập nhật module. Do đó, nếu có chỉnh sửa thì tốt nhất nên chỉnh sửa từ module.

  • Sửa ControlPanelView: Tùy chọn này dùng để mở ra bản ghi ir.ui.view của dạng view tìm kiếm trên model hiện tại.

  • Kích hoạt Gỡ lỗi Assets: Odoo cung cấp 2 loại debug là Chế độ phát triểnChế độ phát triển (có assets), bạn có thể thấy ở hình ảnh dưới đây.

  • Activate Test Assets Debugging Như chúng ta đã biết, Odoo sử dụng các chuyến tham quan để thử nghiệm. Bật chế độ này sẽ tải test asset trong Odoo. Tùy chọn này sẽ hiển thị thêm một số chuyến tham quan trong hộp thoại bắt đầu chuyến tham quan.

  • Tạo gói tài sản: Odoo quản lý tất cả CSSJavaScript thông qua các gói tài sản. Đây là tùy chọn xóa các JavaScript cũ và các tài sản CSS và tạo ra những cái mới. Lựa chọn này rất hữu dụng. Điều này rất có ích khi chúng ta gặp sự cố do bộ nhớ tạm thời (cache).

  • Trở thành Superuser: Đây là tùy chọn mới có từ bản 12. Khi kích hoạt lựa chọn này. Bạn sẽ truy cập hệ thống bằng quyền cao nhất (super user). Bạn có thể truy cập vào các bản ghi nếu bạn không có quyền truy cập, tùy chọn này không có sẵn trên tất cả người dùng, nó chỉ có ở người có quyền quản trị viên Administration: settings. Sau khi kích hoạt chế độ này, bạn sẽ thấy menu trên cùng có sọc như hình dưới đây:

../../_images/become_superuser-05.en.jpg
  • Rời công cụ nhà phát triển: Lựa chọn cho phép bạn thoát khỏi chế độ phát triển.

Chúng ta đã tìm hiểu các tùy chọn có trong menu gỡ lỗi. Các tùy chọn này có thể được sử dụng theo một số cách, chẳng hạn như gỡ lỗi, kiểm thử và giải quyết lỗi. Chúng cũng có thể được sử dụng để khám phá mã nguồn của các giao diện.